🦁

時々コマンドに付いてる--(Double Dash)って何なの?

2022/01/17に公開

こんばんは。株式会社プラハCEO兼エンジニアの松原です。

例えばNode.jsでテストを書いてる時こんなコマンドを見たことはありませんか?

dotenv -e .test.env -- jest --config config.json

.test.envの後に紛れ込んでいる --。これは一体何なのか?

結論

「--」は「これ以降の入力はオプションではありません」と指定する記号です。

bashのドキュメントでその存在について言及されています:

https://www.gnu.org/software/bash/manual/bash.html

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

-- の挙動は実行時の環境やコマンドに依存するため注意が必要です

PrAha

Discussion