LoginSignup
11
7

More than 5 years have passed since last update.

bashに !' で event no found と怒られた理由を考えてみる

Last updated at Posted at 2016-12-14

先日の遭遇した下のエラーについて調べてみた。

$ ruby -e "puts 'Hello, World!'"
bash: !': event no found

「!」とは?

!に続く文字列に一致する最新のコマンドの再実行。
Bashでエクスクラメーションマークで始まるコマンドはどういう意味でしょうか... - Yahoo!知恵袋

Bashにはヒストリ展開という機能がある。
この機能によって、コマンド中の!fooのような文字列は、実行したことのあるfooから始まるコマンドの中で最も最近のものに置き換えられる。
[Bash] ダブルクォートで囲んだコマンド置換中で!を使うとエラーになる(例: echo "$(echo '!')") - Qiita

直近のコマンドを再実行されることが分かったので、ちょっと試してみる。

$ 'uname'
Linux
$ "arch"
x86_64

このコマンドを「!」で再実行

$ !'
'uname'
Linux
$ !"
"arch"
x86_64

なるほど

ということで

$ ruby -e "puts 'Hello, World!'"
bash: !': event no found

この原因はこのコマンド以前に「'」から始まるコマンドを実行していないから、エラーが発生したことを理解。

では、「'」から始まるコマンドがあった場合、どう処理されるのか?

$ 'uname'
Linux
$ ruby -e "puts 'Hello, World!'"
ruby -e "puts 'Hello, World'uname'"
-e:1: syntax error, unexpected tIDENTIFIER, expecting end-of-input
puts 'Hello, World'uname'
                        ^

'uname' が展開されて実行。そして、構文エラー

ちなみに、履歴を辿ると構文エラーのコマンドで残っている。(当然か)

$ ruby -e "puts 'Hello, World'uname'"

ただ、

$ ruby -e 'puts "Hello, World!"'
Hello, World!

こっちのパターン(!")で、展開されない理由が良く分からない…。
'' に囲まれていることによってエスケープされた?

おまけ

$ 'uname'
Linux
$ echo '!'
!
$ echo '"!"'
"!"
$ echo "'!'"
echo "''uname'"
''uname'

最後のコマンドの展開
" ' !' "
   ↓
" ' 'uname' "

11
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7