【问题标题】:unix permissions converter in symbolic notation (including sticky bit)符号表示法的 unix 权限转换器(包括粘滞位)
【发布时间】:2018-04-01 12:09:32
【问题描述】:

我需要得到Access rights in more human readable 格式的文件或文件夹,带有symbolic 符号,如u=rwx,g=srwx,o-rwx(可能是粘性位)

  • 使用stat --format '%a',我得到格式为2770,八进制格式的结果
  • 使用stat --format '%A',我得到格式为drwxrws---的结果,人类可读

我需要一个命令来获取像u=rwx,g=srwx,o-rwx这样的格式(兼容chmod symbolic modes

  • [u|g|o]user/group/othera 所有人
  • [=] : 授予权利
  • [rwxst] : 授予无顺序重要性的权利列表
  • [-rwx] :撤销权利(如果未授予权利)

我试过这个(但它不能处理所有情况,特别是粘性位):

stat --format '%A' temp |
    sed -E 's/^.(...)(...)(...)/u=\1,g=\2,o=\3/g' | # split by triplet
    sed 's/=---/-rwx/g' | # revoker grants
    sed 's/rws/srwx/g'  | # setgid with x ...
    sed 's/--S/s/g'     | # setgid without x ...
    sed ... nead more transormation... # manage  sticky bit setuid setgid

我寻找一种更优雅的方式。

示例输入 ==> 输出

  • drwxrws--- ==> u=rwx,g=srwx,o-rwx(以 d ==> 目录开头)
  • drwxrwxrwx ==> u=rwx,g=rwx,o=rwxugo=rwxa=rwx
  • -r-xrw-r-- ==> u=rx,g=rw,o=r(以 - ==> 常规文件开头)
  • -rwx--S--- ==> u=rwx,g=s,o-rwx(S 大写)
  • ------s--t ==> u=-srwx,g=sx,o=xt (Stickybit)

输入格式 ==> 类似命令statls -al
输出格式==> 必须兼容chmod

这个完整的版本看起来可行,但我相信我们可以简化它,(即没有多个 sed)

stat --format '%A' a |
sed -E 's/^.(...)(...)(...)/u=\1,g=\2,o=\3/g' | # split by triplet    
sed -E 's/s/xs/g'          | # setgid ou setuid with x ...
sed -E 's/t/xt/g'          | # sticky bit with x ...    
sed -E 's/S/s/g'           | # setgid ou setuid without x ...
sed -E 's/T/t/g'           | # sticky bit alone
sed -E 's/-//g'            | # remove -
sed -E 's/=(,|$)/-rwx\1/g'   # revoker grants

【问题讨论】:

  • 为什么要投反对票?请解释一下。
  • 因为您要求别人为您编写代码而您不费吹灰之力。
  • 好的,我已经更新了我的临时解决方案(我没有发布这个不影响回答)
  • 您的规格不完整。例如,您希望 r-xrw-r-- 输出什么?
  • -r-xrw-r-- 可以返回u=rx,g=rw,o=r(顺序不重要)

标签: linux bash unix permissions stat


【解决方案1】:

最后我找到的更简洁的命令是:

stat --format '%A' myFile | sed -E -e 's/(...)(...)(...)$/u=\1,g=\2,o=\3/;s/(s|t)/x\1/g;s/(S|T)/\l\1/g;s/-//g;s/(u|g)=,/\1-rwxs,/g;s/o=$/o-rwxt/g'

我宁愿找到一个原生命令

为了确保我已经编写了详尽的 bash 来测试所有权利组合(8*8*8*8 = 4096 例!)

test_file=/tmp/a

return_code=0

echo -e "from itertools import product;\nfor mod in  product('01234567', repeat=4) : print ''.join(mod)" | python | shuf |
while read octalMod
do
  chmod $octalMod $test_file  # apply octal mod

  # get symbolic mod
  symbolicMod=$(stat --format '%A' $test_file | sed -E -e 's/(...)(...)(...)$/u=\1,g=\2,o=\3/;s/(s|t)/x\1/g;s/(S|T)/\l\1/g;s/-//g;s/(u|g)=,/\1-rwxs,/g;s/o=$/o-rwxt/g')

  chmod 0000 $test_file          # reset mod
  chmod $symbolicMod $test_file  # apply symbolic mod

  modActual=$(stat --format '%a' $test_file) # get actual mod in octal format to compare it with the original
  if [ $octalMod -ne $modActual ]
  then
    echo "$octalMod ($symbolicMod) !!! octalMod=$octalMod <> modActual=$modActual" >&2
    return_code=255
  else
    echo "$octalMod ($symbolicMod)     octalMod=$octalMod == modActual=$modActual" >&1
  fi

done
exit $return_code

完整列表:

test_file=/tmp/a

echo -e "octalMod\thumanMod\tsymbolicMod"

echo -e "from itertools import product;\nfor mod in  product('01234567', repeat=4) : print ''.join(mod)" | python |
while read octalMod
do
  chmod $octalMod $test_file  # apply octal mod

  # get symbolic mod
  symbolicMod=$(stat --format '%A' $test_file | sed -E -e 's/(...)(...)(...)$/u=\1,g=\2,o=\3/;s/(s|t)/x\1/g;s/(S|T)/\l\1/g;s/-//g;s/(u|g)=,/\1-rwxs,/g;s/o=$/o-rwxt/g')
  humanMod=$(stat --format '%A' $test_file)

  echo -e "$octalMod\t$humanMod\t$symbolicMod"

done

echo -e "octalMod\thumanMod\tsymbolicMod"

样本结果:

octalMod        humanMod        symbolicMod
0001    ---------x      u-rwxs,g-rwxs,o=x
0354    --wxr-xr--      u=wx,g=rx,o=r
1210    --w---x--T      u=w,g=x,o=t
3337    --wx-wsrwt      u=wx,g=wxs,o=rwxt
3566    -r-xrwSrwT      u=rx,g=rws,o=rwt
3734    -rwx-wsr-T      u=rwx,g=wxs,o=rt
6734    -rws-wsr--      u=rwxs,g=wxs,o=r
7121    ---s-wS--t      u=xs,g=ws,o=xt
7430    -r-S-ws--T      u=rs,g=wxs,o=t
7611    -rwS--s--t      u=rws,g=xs,o=xt

【讨论】:

    【解决方案2】:

    sed 命令采用多个-e 'sed-command' 选项,因此修复代码以使用一次sed 调用很简单:

    stat --format '%A' a |
    sed -E -e 's/^.(...)(...)(...)/u=\1,g=\2,o=\3/g' \
           -e 's/s/xs/g' \
           -e 's/t/xt/g' \    
           -e 's/S/s/g' \
           -e 's/T/t/g' \
           -e 's/-//g' \
           -e 's/=(,|$)/-rwx\1/g'
    

    您不能使用尾随 cmets,但这与您显示的内容相同。您的 s/s/xs/g 操作与您描述为您想要的输出不匹配(对于具有组执行权限的 SGID,您显示 sx 而不是 xs)。有些人会将所有这些选项压缩成一个 -e 选项,并用分号分隔表达式。我更喜欢使用-e 来分隔单独的选项。有时使用-f script.sed 选项从文件中读取脚本是明智的。我认为此脚本尚未达到该阈值,但不要忘记该选项存在。

    美丽在旁观者的眼中。我不相信权限的替代表示比正常的表示要好得多,但也许我只是使用 Unix 太久了。

    【讨论】:

    • 感谢您的建议,我已经知道 sed 的不同语法。我已经使用“多个”命令轻松添加 cmets。对于xsvs sx,顺序并不重要。对于替代格式的选择,我认为symbolic 语法在我们使用粘滞位时更清晰,大写ST vs st 对我来说是一个hack,因为最初unix 不管理粘性位。我将完成我的问题以详细说明原因。
    猜你喜欢
    • 2013-03-01
    • 1970-01-01
    • 2021-04-17
    • 2020-03-10
    • 2021-01-25
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多