ls -l
から次の出力があるとします。
drwxr-xr-x 2 root root 4096 Apr 7 17:21 foo
これをchmod
で使用される形式に自動的に変換するにはどうすればよいですか?
例えば:
$ echo drwxr-xr-x | chmod-format
755
OS X 10.8.3を使用しています。
一部のシステムには、ファイルの権限を数値として表示するコマンドがありますが、残念ながら移植性はありません。
zsh
には、stat
モジュールにzstat
(別名stat
)が組み込まれています。
zmodload zsh/stat
stat -H s some-file
次に、mode
が$s[mode]
はモードです。つまり、タイプ+パーマです。
8進数で表されるアクセス許可が必要な場合は、次のものが必要です。
perms=$(([##8] s[mode] & 8#7777))
BSD( Apple OS/X を含む)にもstat
コマンドがあります。
mode=$(stat -f %p some-file)
perm=$(printf %o "$((mode & 07777))"
GNU find(1990年までさかのぼり、おそらくそれ以前)は、許可を8進数として出力できます。
find some-file -Prune -printf '%m\n'
後で(2001年、zsh
stat
(1997)の後で、BSDの前にstat
(2002))a GNU stat
コマンドは、別の構文で再び導入されました。
stat -c %a some-file
それらのずっと前に、IRIXには別の構文でstat
コマンドがすでにありました(1994年に IRIX 5. ですでにそこにあります)。
stat -qp some-file
繰り返しますが、標準コマンドがない場合、移植性のための最善の策はPerl
を使用することです:
Perl -e 'printf "%o\n", (stat shift)[2]&07777' some-file
GNU stat
に-c
オプションを使用して8進形式で権限を出力するように依頼できます。man stat
から:
-c --format=FORMAT use the specified FORMAT instead of the default; output a newline after each use of FORMAT ⋮ %a access rights in octal ⋮ %n file name
だからあなたの場合:
bash-4.2$ ls -l foo
-rw-r--r-- 1 manatwork manatwork 0 Apr 7 19:43 foo
bash-4.2$ stat -c '%a' foo
644
または、stat
の出力を有効なコマンドとしてフォーマットすることで自動化することもできます。
bash-4.2$ stat -c "chmod %a '%n'" foo
chmod 644 'foo'
bash-4.2$ stat -c "chmod %a '%n'" foo > setpermission.sh
bash-4.2$ chmod a= foo
bash-4.2$ ls -l foo
---------- 1 manatwork manatwork 0 Apr 7 19:43 foo
bash-4.2$ sh setpermission.sh
bash-4.2$ ls -l foo
-rw-r--r-- 1 manatwork manatwork 0 Apr 7 19:43 foo
ワイルドカードを使用している場合、上記のソリューションは複数のファイルでも機能します。
stat -c "chmod -- %a '%n'" -- *
空白文字を含むファイル名では正しく機能しますが、単一引用符を含むファイル名では失敗します。
シンボリック表記から8進数表記に変換するには、次のようにしてI 一度出てきた を使用します。
chmod_format() {
sed 's/.\(.........\).*/\1/
h;y/rwsxtSTlL-/IIIIIOOOOO/;x;s/..\(.\)..\(.\)..\(.\)/|\1\2\3/
y/sStTlLx-/IIIIIIOO/;G
s/\n\(.*\)/\1;OOO0OOI1OIO2OII3IOO4IOI5IIO6III7/;:k
s/|\(...\)\(.*;.*\1\(.\)\)/\3|\2/;tk
s/^0*\(..*\)|.*/\1/;q'
}
拡張:
#! /bin/sed -f
s/.\(.........\).*/\1/; # extract permissions and discard the rest
h; # store a copy on the hold space
# Now for the 3 lowest octal digits (rwx), translates the flags to
# binary where O means 0 and I means 1.
# l, L are for mandatory locking (a regular file that has 02000 on
# and not 010 on some systems like Linux). Some ls implementations
# like GNU ls confusingly use S there like for directories even though
# it has nothing to do with setgid in that case. Some ls implementations
# use L, some others l (against POSIX which requires an uppercase
# flag for extra flags when the execution bit is not set).
y/rwsxtSTlL-/IIIIIOOOOO/
x; # swap hold and pattern space, to do a second processing on those flags.
# now only consider the "xXlLsStT" bits:
s/..\(.\)..\(.\)..\(.\)/|\1\2\3/
y/sStTlLx-/IIIIIIOO/; # make up the 4th octal digit as binary like before
G; # append the hold space so we now have all 4 octal digits as binary
# remove the extra newline and append a translation table
s/\n\(.*\)/\1;OOO0OOI1OIO2OII3IOO4IOI5IIO6III7/
:k
# translate the OOO -> 0 ... III -> 7 in a loop
s/|\(...\)\(.*;.*\1\(.\)\)/\3|\2/
tk
# trim leading 0s and our translation table.
s/^0*\(..*\)|.*/\1/;q
これは、1つのファイルのls -l
の出力から8進数を返します。
$ echo 'drwSr-sr-T' | chmod_format
7654
Shの下のMacでのこのコマンド
stat -f "%Lp %N" your_files
数値権限のみが必要な場合は、%Lpのみを使用してください。
例えば:
stat -f "%Lp %N" ~/Desktop
700 Desktop
700はchmodで使用できる数値パーミッションで、デスクトップはファイル名です。
あるファイルから権限を取得して別のファイルにも付与することが目的である場合、GNU chmod
にはすでに そのための「参照」オプション 。
Mac OS X(10.6.8)では、stat -f format
を使用する必要があります(実際にはNetBSD/FreeBSD stat
であるため)。
# using Bash
mods="$(stat -f "%p" ~)" # octal notation
mods="${mods: -4}"
echo "$mods"
mods="$(stat -f "%Sp" ~)" # symbolic notation
mods="${mods: -9}"
echo "$mods"
ls -l
によって生成されたシンボリック許可文字列を8進数に変換するには(Shellビルトインのみを使用)、 showperm.bash を参照してください。
# from: showperm.bash
# usage: showperm modestring
#
# example: showperm '-rwsr-x--x'
別の方法として、アクセス許可を保存して後で、または別のファイルに復元する場合は、setfacl/getfacl
を使用します。これにより、ボーナスとして(POSIXドラフト)ACLも復元されます。
getfacl some-file > saved-perms
setfacl -M saved-perms some-other-file
(Solarisでは、-f
ではなく-M
を使用してください)。
ただし、一部のBSDでは使用できますが、ACLがchmod
のみで操作されるApple OS/Xでは使用できません。