rwx/rwt 等与八进制版本之间是否有 shell 脚本转换器?

rwx/rwt 等与八进制版本之间是否有 shell 脚本转换器?

我浏览了剧本

echo 'rwxrwxrw-' | perl -ne 'BEGIN{sub conv{ chomp(my $ins=shift); my $k=0; for(my $i=0;$i<=8;$i++) { my $tmps = ( substr($ins, $i, 1) =~ /[rwx]/ ); $k+= ( $tmps*(2**(8-$i)) ); }; if ($k) { sprintf(" %0o ", $k); } else { "??" ; }; }; } print(conv($_)."\n");'

它确实很棒,但它缺少额外的权限,如粘性位、suid、sgid。如果您能将它们包含在脚本中,我将更加感激。

答案1

这是bash:

perms="rwxr-xr-x"
p=0
for ((i=0; i<${#perms}; i++)); do
    ((p <<= 1))
    [[ ${perms:i:1} == "-" ]] || ((p += 1))
done
printf "%o\n" $p   # ==> 755

不处理粘性位等。为此,请使用stat

$ touch afile
$ chmod 2700 afile
$ ls -l afile
-rwx--S--- 1 jackman jackman 0 Nov 29 09:36 afile*
$ stat -c '%a' afile
2700

Perl 有一个内置的stat功能:

$ perl -e '@fields = stat "afile"; printf "%04o\n", $fields[2] & 07777'
2700

答案2

stat处理 Sticky、setuid 或 setgid 时不需要使用 of (即使它更难处理),并且 BASHism 也是不必要的。 /tmp 的示例适用于没有 BASH 的非常古老的 UNIX:

ls -ld /tmp | \
tee /dev/stderr | \
awk '{ k=0; for(i=0; i<=8; i++) k+=((substr($1, i+2, 1) ~ /[rwxs]/)*2^(8-i));
       if ($1 ~ /^.{3}[Ss]/) k+=2048; if($1 ~ /^.{6}[Ss]/) k+=1024;
       if ($1 ~ /[Tt]/) k+=512; if(k) printf("%04o\n",k) }'
drwxrwxrwt   3 sys      sys         2560 Jul 16 12:39 /tmp
1776

也就是说,格伦·杰克曼perl stat解决方案是首选的简洁性,并且经过少量修改,允许从 shell 变量接受目标(并且也适用于相同的古老 UNIX):

$ what="/tmp"
$ perl -s -e '@fields = stat "$f"; printf "%04o\n", $fields[2] & 07777' -- -f="$what"
1777

awk 脚本基于一个发现的这里

相关内容