Home > Software design >  Ruby cannot stat a file with a pound/hash character
Ruby cannot stat a file with a pound/hash character

Time:09-26

Behold:

bear@ptah:~/Pictures/Wallpapers
$ stat /home/bear/Dropbox/.#NineFoxes.org
  File: /home/bear/Dropbox/.#NineFoxes.org -> [email protected]:1659418908
  Size: 28              Blocks: 0          IO Block: 4096   symbolic link
Device: 10306h/66310d   Inode: 57016400    Links: 1
Access: (0777/lrwxrwxrwx)  Uid: ( 1000/    bear)   Gid: ( 1000/    bear)
Access: 2022-09-23 12:31:49.280214712 -0700
Modify: 2022-08-07 22:25:24.000000000 -0700
Change: 2022-09-23 12:31:49.532216732 -0700
 Birth: 2022-09-23 12:31:49.280214712 -0700
bear@ptah:~/Pictures/Wallpapers
$ stat /home/bear/Dropbox/foo.log
  File: /home/bear/Dropbox/foo.log
  Size: 1471            Blocks: 8          IO Block: 4096   regular file
Device: 10306h/66310d   Inode: 57016411    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/    bear)   Gid: ( 1000/    bear)
Access: 2022-09-23 12:31:49.280214712 -0700
Modify: 2022-09-10 23:28:04.000000000 -0700
Change: 2022-09-23 12:31:50.116221410 -0700
 Birth: 2022-09-23 12:31:49.280214712 -0700
bear@ptah:~/Pictures/Wallpapers
$ irb
irb(main):001:0> File.stat '/home/bear/Dropbox/foo.log'
=> #<File::Stat dev=0x10306, ino=57016411, mode=0100644, nlink=1, uid=1000, gid=1000, rdev=0x0, size=1471, blksize=4096, blocks=8, atime=2022-09-23 12:31:49.280214712 -0700, mtime=2022-09-10 23:28:04 -0700, ctime=2022-09-23 12:31:50.11622141 -0700>
irb(main):002:0> File.stat '/home/bear/Dropbox/.#NineFoxes.org'
Traceback (most recent call last):
        5: from /usr/bin/irb:23:in `<main>'
        4: from /usr/bin/irb:23:in `load'
        3: from /usr/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
        2: from (irb):2
        1: from (irb):2:in `stat'
Errno::ENOENT (No such file or directory @ rb_file_s_stat - /home/bear/Dropbox/.#NineFoxes.org)
irb(main):003:0> 

The filename is simply correct; that is the file and Ruby fails to stat it. Linux can, everything else can. Ruby can stat a file without a hash in it, also. What is needed to render this file usable to Ruby? (No, renaming is not an option; I need to stat the file.)

Note: This is the filename that Dir.glob finds, also. This is the filename that Ruby thinks it has.

irb(main):003:0> x = Dir.glob('Dropbox/*.org', File::FNM_DOTMATCH)
=> ["Dropbox/NineFoxes.org", "Dropbox/.#NineFoxes.org", "Dropbox/Elf.org", "Dropbox/Midra.org"]
irb(main):004:0> File.stat(x[0])
=> #<File::Stat dev=0x10306, ino=57016406, mode=0100744, nlink=1, uid=1000, gid=1000, rdev=0x0, size=38102, blksize=4096, blocks=80, atime=2022-09-23 12:31:49.280214712 -0700, mtime=2022-07-29 22:00:02 -0700, ctime=2022-09-23 12:31:50.11622141 -0700>
irb(main):005:0> File.stat(x[1])
Traceback (most recent call last):
        5: from /usr/bin/irb:23:in `<main>'
        4: from /usr/bin/irb:23:in `load'
        3: from /usr/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
        2: from (irb):5
        1: from (irb):5:in `stat'
Errno::ENOENT (No such file or directory @ rb_file_s_stat - Dropbox/.#NineFoxes.org)
irb(main):006:0> File.stat(x[2])
=> #<File::Stat dev=0x10306, ino=57016408, mode=0100644, nlink=1, uid=1000, gid=1000, rdev=0x0, size=8416, blksize=4096, blocks=24, atime=2022-09-23 12:31:49.280214712 -0700, mtime=2022-09-19 18:08:32 -0700, ctime=2022-09-23 12:31:50.120221442 -0700>
irb(main):007:0> 

Additional: This is Linux, MX Linux 21, ruby 2.7.4p191 (2021-07-07 revision a21a3b7d23) [x86_64-linux-gnu]. The shell is Bash.

CodePudding user response:

File.stat just calls File::Stat.new and that will raise an exception if the file doesn't exist; this is the behaviour you're seeing.

Note that /home/bear/Dropbox/.#NineFoxes.org is a symlink (see the Access: 0777/lrwxrwxrwx in stat's output). Ruby's File.stat documentation doesn't say if it follows symlinks or not but File.lstat says:

Same as File::stat, but does not follow the last symbolic link. Instead, reports on the link itself.

so it is implied that File.stat will follow the symlink and stat what it points to.

So the /home/bear/Dropbox/.#NineFoxes.org symlink does exist but what the symlink references doesn't exist.

  • Related