コマンドchmodを間違った順序で呼び出してみました。chmod file.txt -r
これは何らかの理由で機能しました。chmod file.txt +r
一方、仕事を拒否しました。どうしてこれなの?1つのコマンドが機能し、他のコマンドが機能しない理由は何ですか?
コマンドchmodを間違った順序で呼び出してみました。chmod file.txt -r
これは何らかの理由で機能しました。chmod file.txt +r
一方、仕事を拒否しました。どうしてこれなの?1つのコマンドが機能し、他のコマンドが機能しない理由は何ですか?
回答:
これはGNU chmodが入力を処理する方法の癖であり、すべてのPOSIX互換のchmod実装に移植可能ではありません。
POSIXchmod
coomand-line構文では、GNUchmod
と同様にモードが最初に来る必要があることに注意してください(オプションもモードの前に来る必要があります)。それ以外は、文書化されていない実装の癖です。
次に、この特定の実装でそれが発生する理由について説明します。
ただし、通常は、「
chmod a-w file
」の方が適切であり、「」の動作と異なる動作chmod -w file
をすると(なしで--
)文句を言いchmod a-w file
ます。
簡単に説明すると、によって解析されるオプションにgetopt
は、接頭辞として-
。のようにls -a
、a
オプションです。長い形式にls --all
はall
オプションがあります。rm -rf
(と同等rm -r -f
)にはオプションr
とf
オプションの両方があります。
それ以外はすべて、技術的にオペランドと呼ばれる非オプション引数です。それらの相対的な位置によって意味が決まるため、これらの位置引数を呼び出すのが好きです。ではchmod
、最初の位置引数はモードであり、2番目の位置引数はファイル名です。
最適なモードは、で始まるべきではありません-
。その場合--
、オプションの代わりにオペランドとして構文解析を強制するために使用する必要があります(つまり、使用chmod a-w file
またはのchmod -- -w file
代わりにchmod -w file
。これもPOSIXによって提案されています。
ソースコードを見ると、getoptを使用してコマンドラインオプションを解析していることがわかります。ここでは、次のような「不正な」モードに対する特別な処理があります-w
。
case 'r':
case 'w':
case 'x':
case 'X':
case 's':
case 't':
case 'u':
case 'g':
case 'o':
case 'a':
case ',':
case '+':
case '=':
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
/* Support nonportable uses like "chmod -w", but diagnose
surprises due to umask confusion. Even though "--", "--r",
etc., are valid modes, there is no "case '-'" here since
getopt_long reserves leading "--" for long options. */
あなたの例を挙げます:
chmod a-r file.txt
だろう最も堅牢な呼び出し。chmod +r file.txt
これは、最初の引数が位置としてモードとして解釈されるため機能します。chmod -r file.txt
-r
は短いr
オプションとして解釈され、特殊なケースとして扱われるため、引き続き機能します。chmod -- -r file.txt
は、-r
位置としてモードとして解釈されるため、正しく機能します。--
with --
はオプション-r
として解釈されないため、これはwithoutの場合とは異なります。chmod file.txt -r
-r
は短いr
オプションとして解釈され、特殊なケースとして扱われるため、引き続き機能します。オプションは位置に依存しません。これは、文書化されていない癖を技術的に悪用します。chmod file.txt +r
は+r
オプションではなくオペランドであるため機能しません。最初のオペランド(file.txt
)はモード...として解釈され、解析に失敗します。
a+rwx
など何かをするchmod * +r
、そしてa+rwx
ファイルがグロブ展開で最初に来ることを起こります。