Chmodおよび-r + r


13

コマンドchmodを間違った順序で呼び出してみました。chmod file.txt -rこれは何らかの理由で機能しました。chmod file.txt +r一方、仕事を拒否しました。どうしてこれなの?1つのコマンドが機能し、他のコマンドが機能しない理由は何ですか?

回答:


18

これはGNU chmodが入力を処理する方法の癖であり、すべてのPOSIX互換のchmod実装に移植可能ではありません。

POSIXchmod coomand-line構文でGNUchmodと同様にモードが最初に来る必要があることに注意してください(オプションもモードの前に来る必要があります)。それ以外は、文書化されていない実装の癖です。


次に、この特定の実装でそれが発生する理由について説明します。

マニュアルで示唆されています

ただし、通常は、「chmod a-w file」の方が適切であり、「」の動作と異なる動作chmod -w fileをすると(なしで--)文句を言いchmod a-w fileます。

簡単に説明すると、によって解析されるオプションにgetoptは、接頭辞として-。のようにls -aaオプションです。長い形式にls --allallオプションがあります。rm -rf(と同等rm -r -f)にはオプションrfオプションの両方があります。

それ以外はすべて、技術的にオペランドと呼ばれる非オプション引数です。それらの相対的な位置によって意味が決まるため、これらの位置引数を呼び出すのが好きです。では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)はモード...として解釈され、解析に失敗します。

4
あなたは、たとえば、という名前のファイルを持っている、場合、これは興味深い結果をもたらす可能性があるa+rwxなど何かをするchmod * +r、そしてa+rwxファイルがグロブ展開で最初に来ることを起こります。
ヨルグWミットタグ

1
または、「rm *」の場合は「-rf」という名前のファイル。
エデルディル

@Edheldilうん、あなたは正しい。これは対処する必要があるもののようです(そして、入力が適切に
サニタイズ

OP構文はPOSIXではないことに注意してくださいman7.org/linux/man-pages/man1/getopt.1.html#SCANNING_MODES
スティーブンペニー

@StevenPennyそれは無関係です。まず、リンクされているマンページはセクション1、つまりセクション3のライブラリルーチンではなく、getopt コマンドです。第二に、それは、つまり受け入れられたオプションのリストを参照しています(ソースではに設定されます)。リンクされた「SCANNING MODES」セクションは、プログラムに渡される引数を含む引数配列とは関係ありません。optstringchmodoptstring"Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::" argv
ボブ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.