やりたかったこと
Bash on Windowsで、プロンプト(user@hostname:~$
のやつ)のホスト名の部分を変更したかったのですが、どうもWindows側でマシン名を変えないといけないっぽい。
それは面倒なので、$PS1
をいじって、ホスト名を変えずにプロンプトの表示だけ変えてみます。
元の$PS1
はこんな感じ
$ echo $PS1
\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\u@\h:\w\$
この\h
の部分がホスト名になるので、sedで置換すればいいだろう、ということで以下のようにしてみました。PCがLet's Noteなので、ホスト名はLET'S_NOTE
で。
$ export PS1=`echo $PS1 | sed "s/\\h/LET'S_NOTE/g"`
$ echo $PS1
\[\e]0;\u@\LET'S_NOTE: \w\a\]${debian_cLET'S_NOTEroot:+($debian_cLET'S_NOTEroot)}\u@\LET'S_NOTE:\w\$
はい、見事に失敗です。どうも\\h
のエスケープが上手くいっていないっぽいです。
というわけで、バックスラッシュを増やしてみたところ、上手くいきました。
$ echo `echo $PS1 | sed "s/\\\\\h/LET'S_NOTE/g"`
\[\e]0;\u@LET'S_NOTE: \w\a\]${debian_chroot:+($debian_chroot)}\u@LET'S_NOTE:\w\$
$ echo `echo $PS1 | sed "s/\\\\\\\\\\\\h/LET'S_NOTE/g"`
\[\e]0;\u@LET'S_NOTE: \w\a\]${debian_chroot:+($debian_chroot)}\u@LET'S_NOTE:\w\$
試してみたところ、バックスラッシュ5個〜12個なら上手く行くようです。
でも5個でも12個でも同じ結果って、一体どういう展開がされているのか気になったので、いろいろ試してみました。
シェルのエスケープの展開
""と``
まず、""
の展開の仕方を見てみます。
$ echo "\h"
\h
$ echo "\\h"
\h
$ echo "\\\h"
\\h
$ echo "\\\\h"
\\h
次にコマンド展開の``
。シングルクォートの文字列は展開されないので、それをecho
してコマンド置換してみます。
$ echo '\\h'
\\h
$ echo `echo '\h'`
\h
$ echo `echo '\\h'`
\h
$ echo `echo '\\\h'`
\\h
$ echo `echo '\\\\h'`
\\h
つまり、どちらも\\
は\
に変換し、\h
はそのまま残しているようです。
sedの正規表現のエスケープ展開
次にsedです。
$ echo 'hoge\h' | sed 's/\h/fuga/g'
fugaoge\fuga
$ echo 'hoge\h' | sed 's/\\h/fuga/g'
hogefuga
$ echo 'hoge\h' | sed 's/\\\h/fuga/g'
hogefuga
$ echo 'hoge\h' | sed 's/\\\\h/fuga/g'
hoge\h
こちらはダブルクォートの文字列やコマンド展開とは違い、\h
をh
に変換しているようです。
正規表現だから当たり前といえば当たり前かもしれません。
結果
この結果をもとに先ほどのケースを考えてみると納得できそうです。
以下は、わかりやすいように適宜スペースを入れています。
- バックスラッシュ4個の場合
- バッククォートの展開:
\\ \\ h
が展開され、\ \ h
に - ダブルクォートの展開:
\\ h
が展開され、\ h
に - 正規表現の展開:
\h
が展開され、h
に
- バッククォートの展開:
- バックスラッシュ5個の場合
- バッククォートの展開:
\\ \\ \h
が展開され、\ \ \h
に - ダブルクォートの展開:
\\ \h
が展開され、\ \h
に - 正規表現の展開:
\\ h
が展開され、\ h
に
- バッククォートの展開:
- バックスラッシュ12個の場合
- バッククォートの展開:
\\ \\ \\ \\ \\ \\ h
が展開され、\ \ \ \ \ \ h
に - ダブルクォートの展開:
\\ \\ \\ h
が展開され、\ \ \h
に - 正規表現の展開:
\\ \h
が展開され、\ h
に
- バッククォートの展開:
同様に考えると、6〜11個のときも説明できそうです。
文字列と正規表現の展開のされ方が微妙に違っていることを意識するいい機会になりました。