问题描述
有一个chmod命令来设置文件权限,但是我可以通过命令行以八进制模式(例如755)获得文件权限吗?
最佳解决方案
你可以试试
stat -c "%a %n" *
将*
替换为您想要检查的相关目录或确切文件名。
-c --format=FORMAT
use the specified FORMAT instead of the default; output a newline after
each use of FORMAT
%a Access rights in octal
%n File name
用法:
-
使用文件:
$ stat -c "%a %n" ./Documents/Udev.html 664 ./Documents/Udev.html
-
使用文件夹:
$ stat -c "%a %n" ./Documents/ 755 ./Documents/
次佳解决方案
Linux中的文件权限可以使用Linux stat命令以八进制格式显示。
只需按下键盘上的Ctrl
+ Alt
+ T
即可打开终端。打开时,导航到要在八进制模式下查找文件权限的目录。
stat -c '%A %a %n' *
%人类可读形式的访问权限
%八进制权限
%n文件名
Octal numbers and permissions
You can use octal number to represent mode/permission:
r: 4 w: 2 x: 1
For example, for file owner you can use octal mode as follows. Read, write and execute (full) permission on a file in octal is 0+r+w+x = 0+4+2+1 = 7
Only Read and write permission on a file in octal is 0+r+w+x = 0+4+2+0 = 6
Only read and execute permission on a file in octal is 0+r+w+x = 0+4+0+1 = 5
Use above method to calculate permission for group and others. Let us say you wish to give full permission to owner, read & execute permission to group, and read only permission to others, then you need to calculate permission as follows: User = r+w+x = 0+4+2+1 = 7 Group= r+w+x = 0+4+2+0 = 6 Others = r+w+x = 0+0+0+1 = 1
Effective permission is 761.
来源:http://kmaiti.blogspot.com/2011/09/umask-concept.html
第三种解决方案
正如AgileAdam.com上Adam Courtemanche提供的’ls’的’755’式权限所详细描述的,您可以创建一个别名lso,它的作用类似于ls -l,但稍微处理了output1以显示八进制的权限。这增加了显示三位数字2八进制权限的领先列。正如所写,这适用于大多数文件和目录,但如果设置了sticky或setuid /setgid位,它将无法正常工作。
alias lso="ls -alG | awk '{k=0;for(i=0;i<=8;i++)k+=((substr(\$1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(\" %0o \",k);print}'"
不过,这有一个严重的缺点,就像techtonik points out。将cannot pass arguments与您对ls
命令的lso
别名替换为awk
别名,因为它们被视为awk
的附加参数。因此,您不能在特定文件或目录上运行lso
,也不能将任何选项(如-F
或--color
)传递到lso
。
解决方法是将lso
定义为函数而不是别名。
lso() { ls -alG "$@" | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(" %0o ",k);print}'; }
如果您在shell中以交互方式尝试这种方式,请运行unalias lso
以删除别名 – 您可以在定义函数之前或之后执行此操作。如果你把它放到一个源文件中,比如~/.bashrc
,只需取出alias
行并添加函数定义即可。
为什么这个工作?与别名不同,bash shell functions can take positional parameters,即命令行 arguments。 "$@"
展开为完整参数列表,导致将lso
函数的参数传递给ls
。 (与别名定义不同,函数体不会被引用;因此有必要在$
和"
之前删除\
字符。)
由于您可以将选项传递给lso
,因此您可能希望从定义中删除-a
和-G
选项 – 您可以在需要时手动传递选项。 (-l
选项对于文件权限等详细信息是必需的,因此删除它没有任何好处。)
lso() { ls -l "$@" | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(" %0o ",k);print}'; }
感谢techtonik为pointing out the limitation定义lso
作为别名,从而激励我扩展这篇文章,并将其改为一个函数。
1One可能会注意到这似乎违反了不解析ls
输出的一般规则。 ls
产生非常human-readable输出;这引入了特殊性和局限性,使其通常不适合作为其他命令的输入。在这种情况下,我们解析ls
,因为我们希望保留ls
的确切行为,除了我们添加的一个更改。
2此别名的局限性也适用于其下面显示的功能版本,可能会被视为错误,即使第四个八进制数字为零,它也只显示三个八进制数字。由于jfmercer具有rightly pointed out,因此此处显示的八进制数字不反映粘性位(如果存在),也不反映setuid或setgid位。
3,比仅仅不显示第四个八进制数字严重的是,这种方法假定它们没有被设置,如果它们是 – 如果你在权限字符串中看到t
,s
或S
,那么你应该忽略八进制数字。这是因为这些位是以权限字符串的方式推断的,并没有考虑粘滞的setuid /setgid位。
第四种方案
只是扩展\简化以前的’stat’相关答案:
你可以简单地运行:
stat <path_to_file>
输出将包含八进制许可以及其他信息。
详情(统计版本和示例):
# stat --version
stat (GNU coreutils) 8.4
[user@localhost ~]# touch /tmp/TEST_PERMISSONS
[user@localhost ~]# chmod 644 /tmp/TEST_PERMISSONS
[user@localhost ~]# stat /tmp/TEST_PERMISSONS
File: `/tmp/TEST_PERMISSONS'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 1010058 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2015-08-26 18:58:59.000000000 +0300
Modify: 2015-08-26 18:58:59.000000000 +0300
Change: 2015-08-26 18:59:16.000000000 +0300
注意:(0644 /-rw-r – r–)
第五种方案
为便于携带,您可以使用perl
:
$ 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
如果您想要注意何时发生错误,请尝试:
perl -e '
for (@ARGV) {
print "$!: $_\n" and next unless -e;
printf "%03o %s\n", (stat)[2] & 07777, $_;
}
' *.txt
第六种方案
您可以使用find
和-printf
操作。
ls
不显示八进制权限,但您可以使用此基于find
的变通办法:
find path -printf "%m:%f\n"
例如,要检查我的视频目录:
$ find Videos -printf "%m:%f\n"
755:Videos
%m
格式说明符告诉-printf
操作打印八进制权限,而%f
格式说明符使它打印文件名。
您可以将多个文件名传递给find
。您甚至可以使用球体(例如,find * -printf "%m:%f\n"
)。
您不必使用像-name
或-iname
这样的测试;只需将您感兴趣的文件或目录的名称作为起点传递给find
就足够了。也就是说,如上所示,在find
之后立即提供他们的名字作为参数。
find
可以很好地控制它如何显示输出。特别有两个修改,你可能会觉得有用:
-
默认情况下,
find
递归子目录,类似于ls -R
。如果您不希望find
访问您传递给它的起点的子目录,则可以添加-maxdepth 0
(或使用-maxdepth
和其他值来指示您希望它变得多深)。$ find Documents -maxdepth 0 -printf "%m:%f\n" 755:Documents
-
%f
只显示一个文件名,所以如果find
不得不递归到一个文件,你可能不知道它在哪里。为了显示路径,从找到该文件的起点开始,改为使用%p
。$ find /boot -printf "%m:%p\n" 755:/boot 644:/boot/initrd.img-4.4.0-92-generic 600:/boot/System.map-4.4.0-93-generic 600:/boot/vmlinuz-4.4.0-92-generic 600:/boot/vmlinuz-4.4.0-93-generic ....
有关使用find
命令的更多信息,请参阅man find
。
另一种方法(ls
和awk
)
这可用于使用其权限列出所有目录文件:
ls -l | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/) \
*2^(8-i));if(k)printf("%0o ",k);print}'
这基本上与Adam Courtemanche的lso
别名中的命令相同,that answer引用该命令,只是作为单个命令运行。如果您只使用过一次,或者在罕见的情况下使用,那么您可能不想打扰将其作为别名或shell函数编写。