単一または複数のマイナス記号で始まる名前のファイルがある場合、たとえば--1
多くのコマンドのパラメータとして使用することはできません。走っても
cat --1
ファイルの内容の代わりに、認識されないオプションのエラーメッセージが表示されます。
cat: unrecognized option '--1'
入力しても同じ効果があります
cat "--1"
cat '--1'
cat \-\-1
何も機能しません。 '-'で始まるファイルは、ファイルシステムでは違法ではありませんが、CLIおよびスクリプトでそれらを操作することは非常に困難です。 OK、cat
またはgrep
の場合は使用できます
cat <--1
これは機能しますが
rm --1
どちらも機能せず、このコマンドを他のコマンドに置き換えるのは非常に困難です。結局のところ非常に不快です。そのようなファイル名を使用しないこととは異なる普遍的な回避策はありますか?
ところで、名前ファイルが単一の場合-
そしてほとんどのコマンドはそれをstdin
として理解しますね?
また、スクリプトでmv
コマンドを使用してすべての名前を変更することはできないため、このようなファイル名を使用しないのは難しいでしょう。
慣例では、-
で始まるものはすべてオプションです。これは、-
で始まるファイル名と衝突します。これを回避するために、ほとんどのコマンドは--
をオプションの終わりの番兵として認識します。 --
の後のすべてはオプションとして認識されず、代わりに文字通りファイル名として扱われます。
例えば
cat -- --1
または
rm -rf -- --1
もう1つの方法は、ファイル名をパスで修飾することです。
例えば
cat ./--1
あるいは
cat /home/username/foo/--1
-
で始まるファイル名は絶対に作成しないことをお勧めします。ファイル名には、改行を含むすべての種類の文字を含めることができますが、それが可能であるという理由だけで、それを行う必要があるとは限りません。
あなたの質問に答えるには:なぜcat、grep、その他のコマンドはマイナス記号で始まるファイルを理解できないのですか?コマンドラインは単なる文字列だからです。シェルは、ファイル名の拡張、単語の分割、変数の置換を行いますが、最終的にプログラムは文字列の配列を受け取ります。
オプションを意味する文字列をファイル名を意味する文字列からどのように分離しますか?いくつかの歩哨キャラクターによって。 UNIX/Linuxの世界での慣例では、センチネル文字として-
を使用します。 -
で始まるものはすべてオプションです。まあ、ほとんどすべて。オプションの引数も-
で始まる場合がありますが、これは個々のプログラムの詳細です。
すべてのプログラムがこの規則に準拠しているわけではありません。おそらく最も人気のある例はdd
です。
dd if=/dev/random of=whatfreespace
dd
は、=
記号の後に表示されるため、ファイル名を認識します。
すべてではないにしても、ほとんどのGNUプログラムはGNU getopt規則に準拠しています:短いオプションは-
で始まり、1文字だけの長いオプションです--
で始まり、少なくとも2文字です。--
は、それ自体でオプションの終わりを示し、その後のすべての文字列はオプションとして認識されません。詳細については、 プログラム引数構文)を参照してください。規則 GNU libcマニュアル。
GNU規則に部分的にのみ準拠するプログラムの一例は、find
です。
find -not -name porn -delete
find
は-
を使用してオプションを非オプションと区別しますが、ロングオプションとショートオプションを区別することはありません。 --
をオプションの終わりとして認識します。すべてのプログラムは、オプションやファイル名などを認識する方法を独自の方法で定義できます。
単一の-
をstdinとして解釈する規則も、文字列の配列で検出されたときに単一の-
文字を解釈する方法の規則です。
ダッシュで始まるものはすべてオプションと見なされます。ファイル名の前にパスを追加して、オプションのように見えないようにすることができます。
cat ./--filename
cat -- --filename
を使用すると、オプションの検索を停止することを示します。サードパーティのアプリケーションは破線のファイル名を処理する方法を知らないため、このアプローチには潜在的な問題があります。ただし、cp, rm, cat
などのPOSIXバイナリはこれらのダッシュの処理方法を知っています
より一般的には、次のとおりです。
cat $options_and_or_file_patterns_or_stdin_if_dash
cat "$option_or_file_or_stdin_if_dash"
cat -- "$file_or_stdin_if_dash"
cat < "$file"
cat - < "$file" # same as above