Đây là câu trả lời cho câu hỏi Y (bỏ qua câu hỏi X ), lấy cảm hứng từ nỗ lực của 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
Ở trên có chứa một vài bashism. Phiên bản sau đây có vẻ tuân thủ POSIX:
#!/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
Ghi chú:
Sử dụng:
$ 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
Và, vâng, tôi biết tốt hơn là không sử dụng echo
với văn bản có thể bắt đầu bằng -
; Tôi chỉ muốn sao chép ví dụ sử dụng từ câu hỏi. Lưu ý, rõ ràng, điều này bỏ qua ký tự thứ 0 (nghĩa là hàng đầu d
/ b
/ c
/ -
/ l
/ p
/ s
/ D
) và thứ 10 ( +
/ .
/ @
). Nó giả định rằng những người duy trì ls
sẽ không bao giờ định nghĩa
r
/ R
hoặc w
/ W
là các ký tự hợp lệ ở vị trí thứ ba, thứ sáu hoặc thứ chín (và, nếu họ làm như vậy, họ nên bị đánh bằng gậy ).
Ngoài ra, tôi chỉ tìm thấy đoạn mã sau, theo cas , trong
Cách khôi phục quyền sở hữu nhóm / người dùng mặc định của tất cả các tệp trong / var :
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 ))
Tôi đã kiểm tra mã này (nhưng không kỹ lưỡng) và nó dường như hoạt động, ngoại trừ thực tế là nó không nhận ra l
hoặc L
ở vị trí thứ sáu. Mặc dù vậy, lưu ý rằng mặc dù câu trả lời này vượt trội về tính đơn giản và rõ ràng, nhưng câu trả lời của tôi thực sự ngắn hơn (chỉ tính mã bên trong vòng lặp; mã xử lý một -rwxrwxrwx
chuỗi, không tính bình luận) và nó có thể được rút ngắn hơn bằng cách thay thế
bằng .if condition; then …
condition && …
Tất nhiên, bạn không nên phân tích đầu ra củals
.
stat
. Bạn có không? (Đây là một công cụ GNU, vì vậy hầu hết có sẵn trên Linux, không phải trên Unix.)