Wie in der Bash-Dokumentation klar dargelegtShell-Arithmetik, wenn Sie einer Zahl 0
innerhalb eines arithmetischen Erweiterungsausdrucks ein Präfix voranstellen (z.B, $(( expr ))
), wird es als Oktalzahl behandelt. Ebenso können Sie b#n
für eine Zahl n
in 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.cnf
zu 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 +0044
wahrscheinlich sauberer und portabler ist, da stat
Formatzeichenfolgen 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 printf
mit 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 bitmask
wurden 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 bitmask
wurden 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! "