時々コマンドに付いてる--(Double Dash)って何なの?
例えばNode.jsでテストを書いてる時こんなコマンドを見たことはありませんか?
dotenv -e .test.env -- jest --config config.json
.test.envの後に紛れ込んでいる --
。これは一体何なのか?
結論
「--」は「これ以降の入力はオプションではありません」と指定する記号です。
bashのドキュメントでその存在について言及されています:
Unless otherwise noted, each builtin command documented as accepting options preceded by ‘-’ accepts ‘--’ to signify the end of the options. The :, true, false, and test/[ builtins do not accept options and do not treat ‘--’ specially. The exit, logout, return, break, continue, let, and shift builtins accept and process arguments beginning with ‘-’ without requiring ‘--’. Other builtins that accept arguments but are not specified as accepting options interpret arguments beginning with ‘-’ as invalid options and require ‘--’ to prevent this interpretation.
(趙ざっくり意訳)
基本的に「-」で始まる引数をオプションとして受け取るコマンドは、「--」を渡すことでオプションの終了を示す。
引数は受け取るけどオプションを受け取らないコマンドもある。そういうコマンドは「-」で始まる引数を無効なオプションとして認識してしまうので、「-」で始まる引数を与えるには「--」を使う必要がある
man bashしても--
に関する記述を見つけられます:
-- A -- signals the end of options and disables further option
processing. Any arguments after the -- are treated as file-
names and arguments. An argument of - is equivalent to --.
(超ざっくり意訳)
--
はオプションの終了を示す。--
以降の引数はファイル名や引数として認識される。
例えば --hoge.txtというファイルがディレクトリに存在している状態で rm --hoge.txt
を実行すると何が起きるでしょうか?
> rm --hoge.txt
rm: illegal option -- -
要は「rmコマンドに --hoge.txt というコマンドは存在しないよ!」というエラーが生じています。基本的にbashやzshなどのビルトインコマンドは-
や--
で始まる引数(-hとか--helpとか)をオプションとして認識してしまうので、--hoge.txtもオプションの1つとして認識してしまいます。
ちなみに rm *.txt
を実行した際にも、rmコマンドは失敗します
> rm *.txt
rm: illegal option -- -
これを防ぐためには--を挟んで、「これ以降の入力はオプションではないよ」と伝える必要があります
> rm -- --hoge.txt
注意が必要なケース: -- を解釈しないコマンド
コマンドによっては--をオプション終了記号として解釈しないこともあります。
echoは1つの例です。「-n」という文字列をechoしたいとします。
> echo -n
(何も出力されない)
上記のコマンドは「n」オプションをechoに渡していると認識されてしまいます。じゃあこの記事で学んだ「--」を挟めば良いではないか、と試しても
> echo -- -n
-- -n
-- -n
が出力されてしまいました。出力したいのは-n
なのに。このようにコマンドによっては「--」を解釈しないこともあります。
ちなみにzshだと--
の代わりに-
を使えば以下のように「-n」という文字列をechoできます。
> echo - -n
-n
-- の挙動は実行時の環境やコマンドに依存するため注意が必要です
Discussion