TL;DR
$ # 対話型シェルで
$ echo "もうやだ……"
もうやだ……
$ echo "やだーー!!!!!!"
echo "やだーーecho "もうやだ……"echo "もうやだ……"echo "もうやだ……""
やだーーecho もうやだ……echo もうやだ……echo もうやだ……
ちょっと面白くなるのでやめるべきである。
本文
Bashでは文字列を""
で括ると特殊文字が展開される。
$ # 一番わかりやすいのは変数
$ hoge="ほげ"
$ fuga="ふが"
$ echo "$hoge$fugaぴよ"
ほげふがぴよ
通常この仕様を知っていてもあまり意識せず""
で括ることが多いと思う。特殊文字は展開してくれた方が嬉しい場合が多いからだ。
が、!
に関連する特殊文字については対話型シェルのみで有効になるという性質から、意識したことが無かった。
bashのman (日本語)によると、イベント指示子 (Event Designator)というものらしい。使いそうなものとしては以下の通り。
構文 | 説明 | 例 |
---|---|---|
!! |
直前のコマンドを再実行 | echo "やだー!!" |
!n |
n個目のコマンドライン | echo "やだー!!!1" |
!-n |
n個前のコマンドライン | echo "やだー!-1" |
!string |
直近の string で始まるコマンドライン | echo "やだー!cat なんか飼いたくない!!" |
怖い点
冗談めかして書いているが、参照先でサブシェル($(コマンド)
とか while
とか)を呼びだしていたりするとそのサブシェルが実行されるという挙動をする。
このサブシェルで副作用のある操作をしていたら、「echo
をしただけなのにパソコンが壊れた!!!!」も起こりかねない。
$ cd /home/myName/myWork
$ # 以下のコマンドがたまたまシェル起動から11番目だったとする
$ $(sudo rm -rf ./*) # なぜわざわざサブシェルとかは置いておいて
$
...
$ cd /
$ # 忘れたころに!+数字をecho
$ echo "もうやだ!11"
echo "もうやだ$(sudo rm -rf ./*)" # ←これはBashが出力する行。
もうやだ
$ # ↑この行でシステムが破壊される
気をつけようね。