Bash

如何從 Bash 的算術擴展中返回八進制?

  • June 8, 2019

正如關於shell 算術的 Bash 文件中明確說明的那樣,如果您0在算術擴展表達式(例如, $(( expr )))中為數字添加前綴,則它被視為八進制。同樣,您可以使用baseb#n中的數字。n``b

但是,無論您在表達式中用於算術運算的基數如何,該值始終以 10 為基數返回。如何從算術擴展的結果中返回八進制?

我最初的案例是通過將文件的權限位與位遮罩 AND 一起來警告使用者他們的權限~/.my.cnf太寬鬆(組或世界可讀),但我後來決定測試輸出find ~/.my.cnf -perm +0044是可能更乾淨,更便攜,因為stat格式字元串在 macOS/BSD 和 Linux 之間不是標準的。然而,問題仍然存在。

這是我在另一個 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! "

引用自:https://unix.stackexchange.com/questions/523658