当前位置: 首页>>技术教程>>正文


我怎样才能从命令行获得八进制文件的权限?

, ,

问题描述

有一个chmod命令来设置文件权限,但是我可以通过命令行以八进制模式(例如755)获得文件权限吗?

最佳解决方案

你可以试试

stat -c "%a %n" *

*替换为您想要检查的相关目录或确切文件名。

man page of stat

-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/
    

(Reference)

次佳解决方案

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}'; }

感谢techtonikpointing out the limitation定义lso作为别名,从而激励我扩展这篇文章,并将其改为一个函数。


1One可能会注意到这似乎违反了不解析ls输出的一般规则。 ls产生非常human-readable输出;这引入了特殊性和局限性,使其通常不适合作为其他命令的输入。在这种情况下,我们解析ls,因为我们希望保留ls的确切行为,除了我们添加的一个更改。

2此别名的局限性也适用于其下面显示的功能版本,可能会被视为错误,即使第四个八进制数字为零,它也只显示三个八进制数字。由于jfmercer具有rightly pointed out,因此此处显示的八进制数字不反映粘性位(如果存在),也不反映setuid或setgid位。

3,比仅仅不显示第四个八进制数字严重的是,这种方法假定它们没有被设置,如果它们是 – 如果你在权限字符串中看到tsS,那么你应该忽略八进制数字。这是因为这些位是以权限字符串的方式推断的,并没有考虑粘滞的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

另一种方法(lsawk)

这可用于使用其权限列出所有目录文件:

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函数编写。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/99.html,未经允许,请勿转载。