Wie gebe ich Oktalzahlen aus der arithmetischen Erweiterung von Bash zurück?

Wie gebe ich Oktalzahlen aus der arithmetischen Erweiterung von Bash zurück?

Wie in der Bash-Dokumentation klar dargelegtShell-Arithmetik, wenn Sie einer Zahl 0innerhalb eines arithmetischen Erweiterungsausdrucks ein Präfix voranstellen (z.B, $(( expr ))), wird es als Oktalzahl behandelt. Ebenso können Sie b#nfür eine Zahl nin der Basis verwenden b.

Unabhängig von der Basis, die Sie für die Arithmetik verwenden,innenDer Ausdruck wird immer als Basis 10 zurückgegeben. Wie kann ichzurückkehrenOktal aus dem Ergebnis einer arithmetischen Erweiterung?

Mein ursprünglicher Anwendungsfall hierfür war, einen Benutzer zu warnen, dass die Berechtigungen ~/.my.cnfzu lax waren (gruppen- oder allgemein lesbar), indem ich die Berechtigungsbits der Datei mit einer Bitmaske verknüpfte. Später entschied ich jedoch, dass das Testen der Ausgabe find ~/.my.cnf -perm +0044wahrscheinlich sauberer und portabler ist, da statFormatzeichenfolgen zwischen macOS/BSD und Linux nicht standardisiert sind. Die Frage bleibt jedoch bestehen.

Antwort1

Hier ist ein Leckerbissen, den ich zufällig in einem Kommentar entdeckte inein weiterer SE-Thread: Sie können es einfach printfmit der %o(oktalen) Formatzeichenfolge verwenden.

Ein funktionierendes Beispiel:

# 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

Bonus: andere Lösungen

Wenn ich nicht willsehendie Berechtigungsbits in Oktal, ich könnte mein ursprüngliches Ziel erreichen, ohne printfüberhaupt zu verwenden. Wenn alles, was mich interessiert, ist, obbeliebigder Bits in der bitmaskwurden gesetzt, es reicht aus, einfach zu testen, ob das Ergebnis ungleich Null ist:

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

Wenn Sie wissen wollten, oballedie Bits bitmaskwurden gesetzt, dann vergleichen Sie das Ergebnis der UND-Verknüpfung mit der Bitmaske, etwa so:

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

verwandte Informationen