「-」で始まるファイル名を誤って解釈しないように引用符を使用しないのはなぜですか? [コピー]

「-」で始まるファイル名を誤って解釈しないように引用符を使用しないのはなぜですか? [コピー]

これはとんでもない投稿かもしれませんが、という名前のファイルがあると仮定すると、-|h4k3r|-この参照が機能しないのはなぜですか?

cat '-|h4k3r|-'

一重引用符がすべての特殊文字の意味を削除すると思いましたか?

しかし、これはうまくいきます

cat -- -\|h4k3r\|- 

これはまた:

cat "./-|h4k3r|-"

しかし、なぜこれがうまくいかないのかわかりませんか?

cat "-|h4k3r|-"

この例では、参照が期待どおりに機能しない理由を理解しようとしています。

'-たぶんBashは、"-または??に特別な意味を持つかもしれません。

答え1

その理由は、一重引用符は実際に特殊文字の意味を削除しますが、これは以下を参照するためです。変数拡張、ワイルドカード、単語分割- その特殊文字皮をむくシェルとして解釈される結果がプログラムに渡される前に- とシェルメタ文字(例|:)。

この意味では-「特殊文字」ではありません。特別な点は実はプログラムが開始する文字列をプログラムに表示する標準的な方法は、「オプション」引数です。実際、Unix / Linuxエコシステムのほとんどではありませんが、多くのプログラムは外部リソースに依存しています。getopt()この目的で使用される関数1は、コマンドライン引数を処理する標準化された方法を提供するPOSIX仕様の一部であり、-「オプション」で始まる引数を解釈する規則がここに含まれています。

したがって、一重引用符は-|h4ker|-シェルからプログラムに逐語的に渡されることを保証します(catあなたの場合)。しかし、その過程で引用符も削除されました。。したがって、プログラムはまだこのパラメータがaで始まるので、-オペランド(処理するファイル名など)ではなく「オプション」パラメータとして処理する必要があると思います。

これが多くのプログラム(それに依存するすべてのプログラムgetopt())が--コマンドラインのトークンを特別な「オプションの終わり」マークとして解釈することで始まるファイルに安全に適用できる理由です-

調査ですでに検索されているもう1つの可能性は、ファイル名を絶対ファイル名('/path/to/file/-|h4ker|-')として宣言するか、現在のディレクトリ('./-|h4ker|-')を追加してファイル名を「保護」することです。これにより、パラメータはもはや「あいまいな」始まりで終わりません-この例では依然として引用符/エスケープが必要です。|これはシェルメタ文字だからです。

良いデモは、次のファイルを作成して一覧表示することです-l

~$ touch '-l'
touch: Invalid option -- l
~$ touch -- '-l'
~$ ls '-l'

< ... the entire directory content in long list format ... >

~$ ls -- '-l'
-l
~$ ls -l -- '-l'
-rw-r--r-- 1 user user 0 Feb 24 17:16 -l

1シェルスクリプトの場合、それに対応するスクリプトがあります。getopts組み込みコマンド

答え2

持つ二つプログラムはここで動作します。
1つはシェル、もう1つはcatプログラム/実行ファイル/ユーティリティです。

シェルは「引用」オプションで一重引用符を保持しますが、catはそうではありません。

シェルは-(引数から)初期ダッシュ()に特別な意味を与えませんが、catはそうです。

シェルは、いくつかの規則に従って実行プログラムのパラメータを変更します。

$ echo '-|h4k3r|-'
-|h4k3r|-

$ echo "-|h4k3r|-"
-|h4k3r|-

$ echo -\|h4k3r\|-
-|h4k3r|-

このechoコマンドは同じ引数-|h4k3r|-(引用符を削除した後)を受け取り、上記の3つの場合すべて同じ結果を出力します。さんの参照が|削除されました。特別な殻に意味があります。

このechoコマンドにはほとんどオプションがなく、初期ダッシュ(-)を完全に理解していないため、追加の作業は不要です。

ただし、ページに記載されているcatように多くのオプションがあります。man catオプションは通常、および-で始まります。みんな次の文字は-コマンドで処理する必要がありますcat(一部のオペレーティングシステムでは該当しません)。たとえば、cat -n fileファイルの各行には番号が付けられています。

$ cat file
Line 1
Line 2

$ cat -n file
    1 Line 1
    2 Line 2

ただし、optionsで終わり、--まだaを追加すると、-nファイル名として解釈されますcat

$ cat -- -n file
cat: -n: No such file or directory
Line 1
Line 2

これは、ファイル名(実際にはパス)を、./または..//このディレクトリ、親ディレクトリ、ルートディレクトリ)から始めて直接書き込むことができるためです。

関連情報