質問: Anaconda で使われているシェルスクリプトのソースコードを眺めていたところ、`eval`、`export`、`local` などのコマンド名の前にバックスラッシュが付けられていることに気づきました。 ``` \export CONDA_SHLVL=0 ``` この行頭のバックスラッシュにはどのような意味がありますか?
回答: よくあるのは、スクリプトが **インタラクティブに** 実行される際、そのコマンドが alias されていても無視する、という意味です (Anaconda のリポジトリのコミット・メッセージに言及が無いため本当のところは分かりません)。なお、インタラクティブでない場合においては設定しない限り alias が展開されないため、バックスラッシュがあってもなくても同じです。 ただし、alias を回避するという意味ではバックスラッシュではなく `command` コマンド / `builtin` コマンドや `shopt -u expand_aliases` を使うべきだと思います。 詳細な説明 POSIX シェルの仕様は、alias の代入について以下のように書いています。 > > After a token has been delimited, but before applying the grammatical rules in Shell Grammar, a resulting word that is identified to be the command name word of a simple command shall be examined to determine whether it is an unquoted, valid alias name. > > > つまり alias によってコマンドが書き換えられるのは、トークン分割の直後です。バックスラッシュは文字をエスケープしますが、トークン分割時は例外を除いてエスケープの変換がなされないため、たとえば `\export` は `\export` のまま alias があるかどうか判定されることになります。したがってたとえ `export` に alias があったとしても、`\export` は変換されません。そしてこの後エスケープが処理され、`export` が呼び出されることになります。 ここからは余談ですが、上の仕組みを見ると実はコマンドの先頭にバックスラッシュを持ってくる必要性は無いことに気づきます。先頭にバックスラッシュを置く方法がよく使われているというだけです。たとえば `export` にしか alias が無いのであれば、次のように書くとどれも alias を回避します。 ``` \export ex\port \e\x\p\o\r\t "export" "e"xport 'ex'port 'ex'"port" ``` なお、バックスラッシュで alias による変換は避けられても、 **シェルの関数による変換は避けられていない** ことに注意してください。両者共に回避したい場合、`command` コマンド や `builtin` コマンドを使う方法があります。ただし `command` という名前のシェル関数が定義されていると上手く動きません。詳しくはこの投稿をご覧ください。 関連した投稿 * "Why start a shell command with a backslash?" -- Stack Overflow