Hier ist eine Antwort auf Frage Y (ohne Rücksicht auf Frage X ), inspiriert von dem Versuch des OP:
#!/bin/bash
LC_COLLATE=C
while read ls_out
do
extra=0
perms=0
for i in {1..9}
do
# Shift $perms to the left one bit, so we can always just add the LSB.
let $((perms*=2))
this_char=${ls_out:i:1}
# If it's different from its upper case equivalent,
# it's a lower case letter, so the bit is set.
# Unless it's "l" (lower case L), which is special.
if [ "$this_char" != "${this_char^}" ] && [ "$this_char" != "l" ]
then
let $((perms++))
fi
# If it's not "r", "w", "x", or "-", it indicates that
# one of the high-order (S/s=4000, S/s/L/l=2000, or T/t=1000) bits
# is set.
case "$this_char" in
([^rwx-])
let $((extra += 2 ** (3-i/3) ))
esac
done
printf "%o%.3o\n" "$extra" "$perms"
done
Das Obige enthält ein paar Bashismen. Die folgende Version scheint POSIX-kompatibel zu sein:
#!/bin/sh
LC_COLLATE=C
while read ls_out
do
extra=0
perms=0
for i in $(seq 1 9)
do
# Shift $perms to the left one bit, so we can always just add the LSB.
: $((perms*=2))
this_char=$(expr "$ls_out" : ".\{$i\}\(.\)")
# Lower case letters other than "l" indicate that permission bits are set.
# If it's not "r", "w", "x", or "-", it indicates that
case "$this_char" in
(l)
;;
([a-z])
: $((perms+=1))
esac
# If it's not "r", "w", "x", or "-", it indicates that
# one of the high-order (S/s=4000, S/s/L/l=2000, or T/t=1000) bits
# is set.
case "$this_char" in
([!rwx-])
: $((extra += 1 << (3-i/3) ))
esac
done
printf "%o%.3o\n" "$extra" "$perms"
done
Anmerkungen:
Verwendung:
$ echo drwxr-xr-x | chmod-format
0755
$ echo -rwsr-sr-x | chmod-format
6755
$ echo -rwSr-Sr-- | chmod-format
6644
$ echo -rw-r-lr-- | chmod-format
2644
$ echo ---------- | chmod-format
0000
Und ja, ich weiß, dass es besser ist, keinen echo
Text zu verwenden, der damit beginnt -
. Ich wollte nur das Anwendungsbeispiel aus der Frage kopieren. Beachten Sie , offensichtlich, dass dies ignoriert die 0 - ten Zeichen (dh der führenden d
/ b
/ c
/ -
/ l
/ p
/ s
/ D
) und der 10. ( +
/ .
/ @
). Es wird davon ausgegangen, dass die Betreuer von ls
niemals
r
/ R
oder w
/ W
als gültige Zeichen in der dritten, sechsten oder neunten Position definieren werden (und wenn dies der Fall ist, sollten sie mit Stöcken geschlagen werden ).
Außerdem habe ich gerade den folgenden Code von cas unter
So stellen Sie die standardmäßige Gruppen- / Benutzereigenschaft aller Dateien unter / var wieder her :
let perms=0
[[ "${string}" = ?r???????? ]] && perms=$(( perms + 400 ))
[[ "${string}" = ??w??????? ]] && perms=$(( perms + 200 ))
[[ "${string}" = ???x?????? ]] && perms=$(( perms + 100 ))
[[ "${string}" = ???s?????? ]] && perms=$(( perms + 4100 ))
[[ "${string}" = ???S?????? ]] && perms=$(( perms + 4000 ))
[[ "${string}" = ????r????? ]] && perms=$(( perms + 40 ))
[[ "${string}" = ?????w???? ]] && perms=$(( perms + 20 ))
[[ "${string}" = ??????x??? ]] && perms=$(( perms + 10 ))
[[ "${string}" = ??????s??? ]] && perms=$(( perms + 2010 ))
[[ "${string}" = ??????S??? ]] && perms=$(( perms + 2000 ))
[[ "${string}" = ???????r?? ]] && perms=$(( perms + 4 ))
[[ "${string}" = ????????w? ]] && perms=$(( perms + 2 ))
[[ "${string}" = ?????????x ]] && perms=$(( perms + 1 ))
[[ "${string}" = ?????????t ]] && perms=$(( perms + 1001 ))
[[ "${string}" = ?????????T ]] && perms=$(( perms + 1000 ))
Ich habe diesen Code getestet (aber nicht gründlich), und es scheint zu funktionieren, abgesehen von der Tatsache, dass er nicht erkannt wird l
oder L
an sechster Stelle steht. Beachten Sie jedoch, dass meine Antwort zwar in Bezug auf Einfachheit und Klarheit überlegen ist, meine jedoch kürzer ist (nur der Code in der Schleife wird gezählt; der Code, der eine einzelne -rwxrwxrwx
Zeichenfolge verarbeitet, ohne Kommentare zu zählen) durch Ersetzen
durch .if condition; then …
condition && …
Natürlich solltenls
Sie die Ausgabe von nicht analysieren .
stat
. Hast Du es? (Es ist ein GNU-Tool, das hauptsächlich unter Linux und nicht unter Unix verfügbar ist.)