如何從 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! "

相關內容