如何使用 Ruby 获得八进制文件权限?
How can I get octal file permissions with Ruby?
我使用 perl 阅读 another answer for how to get the 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
class and the #printf
方法。但是,我的所有输出都获得前导 100。
$ 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
- 如果我使用的是 macOS 计算机,前 100 是什么意思?
- 为什么我的
"%04o"
不起作用?
- 如何实现与链接的 perl 脚本相同的输出?
如果您查看 libc 手册的第二部分(shell 中的man 2 stat
),您应该会看到如下内容:
The status information word st_mode has the following bits:
#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 */
确切的内容不会完全相同,但八进制值在任何 Unixy 系统上都应该相同。
您感兴趣的部分是 "this is a regular file" 位:
#define S_IFREG 0100000 /* regular */
这就是您的前导 100
的来源。
如果您回顾一下 Perl 版本,您会发现他们正在应用位掩码:
(stat)[2] & 07777
^^^^^^^
只获取权限位。如果你在 Ruby:
中做同样的事情
printf "%04o\t#{f}\n", (File.stat(f).mode & 07777)
# ----------------------------------------^^^^^^^
您将获得您期望的那种输出。
如果您没有 libc 手册页,那么您可以查看 OpenGroup's stat
documentation which will point you at the struct stat
documentation,其中涵盖了模式中的各个位:
┌─────────┬───────────┬───────────────────────────────────────────┐
│ Name │ Numeric │ Description │
│ │ Value │ │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IRWXU │ 0700 │ Read, write, execute/search by owner. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IRUSR │ 0400 │ Read permission, owner. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IWUSR │ 0200 │ Write permission, owner. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IXUSR │ 0100 │ Execute/search permission, owner. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IRWXG │ 070 │ Read, write, execute/search by group. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IRGRP │ 040 │ Read permission, group. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IWGRP │ 020 │ Write permission, group. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IXGRP │ 010 │ Execute/search permission, group. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IRWXO │ 07 │ Read, write, execute/search by others. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IROTH │ 04 │ Read permission, others. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IWOTH │ 02 │ Write permission, others. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IXOTH │ 01 │ Execute/search permission, others. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_ISUID │ 04000 │ Set-user-ID on execution. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_ISGID │ 02000 │ Set-group-ID on execution. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_ISVTX │ 01000 │ On directories, restricted deletion flag. │
└─────────┴───────────┴───────────────────────────────────────────┘
What does the leading 100 mean given I'm on a macOS machine?
File::Stat#mode
方法的 return 值取决于平台,显然,这就是它在您的平台上 return 的值。
特别是,文档说对于 Unix 机器,使用 stat(2)
中的定义,on macOS 如下:
The status information word st_mode has the following bits:
#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
是
- 常规文件,不是 fifo、字符设备、目录、块设备、符号链接、套接字或 whiteout
- 不适应
- 不是 sgid
- 不粘
- 可读可写,但不能被其所有者执行
- 组可读,但不可写或可执行
- 其他人可读,但不可写或可执行
Why does my "%04o"
not work?
%04o
表示 "format as octal, minimum length 4, pad with zeroes if length is less than 4"。这正是它的作用。
How do I achieve the same output as the linked perl script?
如果你想获得相同的输出,你应该做同样的事情:Perl 脚本从模式中屏蔽掉文件类型,如果你在 Ruby 中做同样的事情,你应该得到相同的结果结果:
Dir["**/**"].each { |f| printf "%04o\t#{f}\n", File.stat(f).mode & 07777 }
它应该很简单:
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
我使用 perl 阅读 another answer for how to get the 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
class and the #printf
方法。但是,我的所有输出都获得前导 100。
$ 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
- 如果我使用的是 macOS 计算机,前 100 是什么意思?
- 为什么我的
"%04o"
不起作用? - 如何实现与链接的 perl 脚本相同的输出?
如果您查看 libc 手册的第二部分(shell 中的man 2 stat
),您应该会看到如下内容:
The status information word st_mode has the following bits:
#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 */
确切的内容不会完全相同,但八进制值在任何 Unixy 系统上都应该相同。
您感兴趣的部分是 "this is a regular file" 位:
#define S_IFREG 0100000 /* regular */
这就是您的前导 100
的来源。
如果您回顾一下 Perl 版本,您会发现他们正在应用位掩码:
(stat)[2] & 07777
^^^^^^^
只获取权限位。如果你在 Ruby:
中做同样的事情printf "%04o\t#{f}\n", (File.stat(f).mode & 07777)
# ----------------------------------------^^^^^^^
您将获得您期望的那种输出。
如果您没有 libc 手册页,那么您可以查看 OpenGroup's stat
documentation which will point you at the struct stat
documentation,其中涵盖了模式中的各个位:
┌─────────┬───────────┬───────────────────────────────────────────┐
│ Name │ Numeric │ Description │
│ │ Value │ │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IRWXU │ 0700 │ Read, write, execute/search by owner. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IRUSR │ 0400 │ Read permission, owner. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IWUSR │ 0200 │ Write permission, owner. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IXUSR │ 0100 │ Execute/search permission, owner. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IRWXG │ 070 │ Read, write, execute/search by group. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IRGRP │ 040 │ Read permission, group. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IWGRP │ 020 │ Write permission, group. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IXGRP │ 010 │ Execute/search permission, group. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IRWXO │ 07 │ Read, write, execute/search by others. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IROTH │ 04 │ Read permission, others. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IWOTH │ 02 │ Write permission, others. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_IXOTH │ 01 │ Execute/search permission, others. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_ISUID │ 04000 │ Set-user-ID on execution. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_ISGID │ 02000 │ Set-group-ID on execution. │
├─────────┼───────────┼───────────────────────────────────────────┤
│ S_ISVTX │ 01000 │ On directories, restricted deletion flag. │
└─────────┴───────────┴───────────────────────────────────────────┘
What does the leading 100 mean given I'm on a macOS machine?
File::Stat#mode
方法的 return 值取决于平台,显然,这就是它在您的平台上 return 的值。
特别是,文档说对于 Unix 机器,使用 stat(2)
中的定义,on macOS 如下:
The status information word st_mode has the following bits:
#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
是
- 常规文件,不是 fifo、字符设备、目录、块设备、符号链接、套接字或 whiteout
- 不适应
- 不是 sgid
- 不粘
- 可读可写,但不能被其所有者执行
- 组可读,但不可写或可执行
- 其他人可读,但不可写或可执行
Why does my
"%04o"
not work?
%04o
表示 "format as octal, minimum length 4, pad with zeroes if length is less than 4"。这正是它的作用。
How do I achieve the same output as the linked perl script?
如果你想获得相同的输出,你应该做同样的事情:Perl 脚本从模式中屏蔽掉文件类型,如果你在 Ruby 中做同样的事情,你应该得到相同的结果结果:
Dir["**/**"].each { |f| printf "%04o\t#{f}\n", File.stat(f).mode & 07777 }
它应该很简单:
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