鉴于它是bash
,您可以执行以下操作:
printf "%.4o\n" $(( $(stat -f '0%Lp' "$file") & ~$(umask) ))
至少,在 Mac OS X 上,这stat -f '%Lp'
意味着“以八进制打印用户、组和其他权限”。如果您使用的是 Linux,则需要将其转换为 GNUstat
语法,看起来可能是:
printf "%.4o\n" $(( $(stat --printf '%a' "$file") & ~$(umask) ))
$((
前后的空格))
并不是严格需要的,因为即使它们丢失,shell 也知道要做什么;周围的空间也是如此&
。OTOH,如果其他人必须阅读代码,您可能想要那些空格。
测试代码:
file="./mode-file"
trap "rm -f $file; exit 1" 0 1 2 3 13 15
cp /dev/null "$file"
for mode in 777 755 644 640 444 440 400
do
chmod $mode $file
ls -l $file
for umask in 002 022 027 033 037 077 177
do
umask $umask
printf "$mode & ~$umask = %.4o\n" $(( $(stat -f '0%Lp' "$file") & ~$(umask) ))
done
done
rm -f $file
trap 0
示例输出:
-rwxrwxrwx 1 jleffler staff 0 Nov 11 20:57 ./mode-file
777 & ~002 = 0775
777 & ~022 = 0755
777 & ~027 = 0750
777 & ~033 = 0744
777 & ~037 = 0740
777 & ~077 = 0700
777 & ~177 = 0600
-rwxr-xr-x 1 jleffler staff 0 Nov 11 20:57 ./mode-file
755 & ~002 = 0755
755 & ~022 = 0755
755 & ~027 = 0750
755 & ~033 = 0744
755 & ~037 = 0740
755 & ~077 = 0700
755 & ~177 = 0600
-rw-r--r-- 1 jleffler staff 0 Nov 11 20:57 ./mode-file
644 & ~002 = 0644
644 & ~022 = 0644
644 & ~027 = 0640
644 & ~033 = 0644
644 & ~037 = 0640
644 & ~077 = 0600
644 & ~177 = 0600
-rw-r----- 1 jleffler staff 0 Nov 11 20:57 ./mode-file
640 & ~002 = 0640
640 & ~022 = 0640
640 & ~027 = 0640
640 & ~033 = 0640
640 & ~037 = 0640
640 & ~077 = 0600
640 & ~177 = 0600
-r--r--r-- 1 jleffler staff 0 Nov 11 20:57 ./mode-file
444 & ~002 = 0444
444 & ~022 = 0444
444 & ~027 = 0440
444 & ~033 = 0444
444 & ~037 = 0440
444 & ~077 = 0400
444 & ~177 = 0400
-r--r----- 1 jleffler staff 0 Nov 11 20:57 ./mode-file
440 & ~002 = 0440
440 & ~022 = 0440
440 & ~027 = 0440
440 & ~033 = 0440
440 & ~037 = 0440
440 & ~077 = 0400
440 & ~177 = 0400
-r-------- 1 jleffler staff 0 Nov 11 20:57 ./mode-file
400 & ~002 = 0400
400 & ~022 = 0400
400 & ~027 = 0400
400 & ~033 = 0400
400 & ~037 = 0400
400 & ~077 = 0400
400 & ~177 = 0400
注意:在 Mac OS X 10.9 (Mavericks) 上测试。如果您使用的是 GNU/Linux 平台,则必须更改stat
命令以使用适用于您的机器的表示法。