我已阅读another answer了解如何使用perl获取octal file permissions:
$ perl -e 'printf "%04o %s\n", (stat)[2] & 07777, $_ for @ARGV' *.txt
0644 1.txt
0644 2.txt
0644 3.txt
0644 4.txt
0600 PerlOneLiner.txt
0664 perl.txt
到目前为止,我已经使用了File::Stat
类和#printf
方法。但是,我的所有输出都是领先的。
$ ruby -e 'Dir["**/**"].each { |f| printf "%04o\t#{f}\n", File.stat(f).mode }'
100711 cplink
100644 hello_world.rb
100755 lso
100711 rename_images
"%04o"
无效?答案 0 :(得分:9)
如果您查看libc手册的第二部分(shell中的Enumerable.Where
),您会看到如下内容:
状态信息字st_mode具有以下位:
man 2 stat
精确的内容不会完全相同,但任何Unixy系统的八进制值都应该相同。
您感兴趣的部分是“这是一个常规文件”位:
#define S_IFMT 0170000 /* type of file */
#define S_IFIFO 0010000 /* named pipe (fifo) */
#define S_IFCHR 0020000 /* character special */
#define S_IFDIR 0040000 /* directory */
#define S_IFBLK 0060000 /* block special */
#define S_IFREG 0100000 /* regular */
#define S_IFLNK 0120000 /* symbolic link */
#define S_IFSOCK 0140000 /* socket */
#define S_IFWHT 0160000 /* whiteout */
#define S_ISUID 0004000 /* set user id on execution */
#define S_ISGID 0002000 /* set group id on execution */
#define S_ISVTX 0001000 /* save swapped text even after use */
#define S_IRUSR 0000400 /* read permission, owner */
#define S_IWUSR 0000200 /* write permission, owner */
#define S_IXUSR 0000100 /* execute/search permission, owner */
这就是您的领导#define S_IFREG 0100000 /* regular */
的来源。
如果你回顾一下Perl版本,你会发现他们正在应用一些掩码:
100
只获取权限位。如果你在Ruby中做同样的事情:
(stat)[2] & 07777
^^^^^^^
你会得到你期望的那种输出。
如果您没有libc手册页,那么您可以查看OpenGroup's stat
documentation,它将指向struct stat
documentation,其中涵盖模式中的各个位:
printf "%04o\t#{f}\n", (File.stat(f).mode & 07777)
# ----------------------------------------^^^^^^^
答案 1 :(得分:2)
在macOS机器上给出的100分是什么意思?
File::Stat#mode
方法的返回值取决于平台,显然是它在您的平台上返回的内容。
特别是,文档说对于Unix机器,使用stat(2)
的定义,on macOS如下:
状态信息字st_mode具有以下位:
#define S_IFMT 0170000 /* type of file */ #define S_IFIFO 0010000 /* named pipe (fifo) */ #define S_IFCHR 0020000 /* character special */ #define S_IFDIR 0040000 /* directory */ #define S_IFBLK 0060000 /* block special */ #define S_IFREG 0100000 /* regular */ #define S_IFLNK 0120000 /* symbolic link */ #define S_IFSOCK 0140000 /* socket */ #define S_IFWHT 0160000 /* whiteout */ #define S_ISUID 0004000 /* set user id on execution */ #define S_ISGID 0002000 /* set group id on execution */ #define S_ISVTX 0001000 /* save swapped text even after use */ #define S_IRUSR 0000400 /* read permission, owner */ #define S_IWUSR 0000200 /* write permission, owner */ #define S_IXUSR 0000100 /* execute/search permission, owner */
这与Single Unix Specification中的描述相符,因此所有 Unices或多或少都是正确的,而不仅仅是macOS。 (macOS有额外的" whiteout"文件类型,它与Time Machine,AFAIK相关,但没关系,SUS允许其他文件类型和权限位。)
所以,如果我正确解读,那就意味着hello_world.rb
是
为什么我的
"%04o"
不起作用?
%04o
表示"格式为八进制,最小长度为4,如果长度小于4&#34,则填充零。而这正是它的作用。
如何实现与链接的perl脚本相同的输出?
如果你想获得相同的输出,你应该做同样的事情:Perl脚本从模式掩盖文件类型,如果你在Ruby中做同样的事情,你应该得到相同的结果:
Dir["**/**"].each { |f| printf "%04o\t#{f}\n", File.stat(f).mode & 07777 }
答案 2 :(得分:0)
应该如此简单:
path = "file_with_0755"
File.stat(path).mode.to_s(8).split("")[-4..-1].join
# => "0755"
File.stat(path).mode.to_s(8).split("")[-4..-1].join.to_i(8) == 0755
# => true