如何从 Bash 算术扩展中返回八进制?

如何从 Bash 算术扩展中返回八进制?

正如 Bash 文档中明确阐述的那样壳算术0,如果在算术扩展表达式中为数字添加前缀 a (例如, $(( expr ))),它被视为八进制。同样,您可以使用for基数中的b#n数字。nb

但是,无论您用于算术的基数如何里面表达式中,值始终以 10 为基数返回。我该如何做返回算术展开结果的八进制?

我最初的用例是通过将文件的权限位与位掩码进行“与”运算来警告用户其权限~/.my.cnf过于宽松(组可读或全局可读),但我后来决定测试的输出find ~/.my.cnf -perm +0044是可能更干净、更便携,因为stat格式字符串在 macOS/BSD 和 Linux 之间不是标准的。然而,问题仍然存在。

答案1

这是我在评论中偶然发现的一个花絮另一个SE线程:您可以仅printf%o(八进制)格式字符串一起使用。

一个工作示例:

# figure out stat(1) flags based on OS
if [[ $(uname -s) == Linux ]]; then PERMS='-c %a' else PERMS='-f %Lp'; fi

stat $PERMS ~/.my.cnf
# result: 600 (not group/world readable)

# permission bits if group/world readable
bitmask=044
perm=$(stat $PERMS ~/.my.cnf)
printf "%o\n" $(( 0$perm & 0$bitmask ))
# result: 0

# now make the file group-readable and try again
chmod 640 ~/.my.cnf
perm=$(stat $PERMS ~/.my.cnf)
printf "%o\n" $(( 0$perm & 0$bitmask ))
# result: 40

奖励:其他解决方案

如果我不想八进制的权限位,我printf根本不用使用就可以实现我最初的目标。如果我只关心是否任何设置中的位bitmask,只需测试结果是否非零就足够了:

if (( 0$perm & 0$bitmask )); then
    echo "Permissions $perm are too lax." >&2
fi

如果你想知道是否全部设置中的位bitmask,然后将它们与位掩码进行“与”运算的结果进行比较,如下所示:

(( (0777 & 0066) == 0066 )) && echo "Oh noes, group AND world writable! "

相关内容