Pertanyaan Apa itu "-bash:!": Event tidak ditemukan "


Coba jalankan yang berikut di bawah shell bash echo "Reboot your instance!"

Pada instalasi saya:

root@domU-12-31-39-04-11-83:/usr/local/bin# bash --version
GNU bash, version 4.1.5(1)-release (i686-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
root@domU-12-31-39-04-11-83:/usr/local/bin# uname -a
Linux domU-12-31-39-04-11-83 2.6.35-22-virtual #35-Ubuntu SMP Sat Oct 16 23:57:40 UTC 2010 i686 GNU/Linux
root@domU-12-31-39-04-11-83:/usr/local/bin# echo "Reboot your instance!"
-bash: !": event not found

Adakah yang bisa menjelaskan apa itu "bash event?" Saya belum pernah mendengar konsep ini sebelumnya. Juga, bagaimana saya harus menampilkan "!" di akhir kalimat?


88
2017-12-02 10:45






Jawaban:


Anda dapat menonaktifkan penggunaan subtitusi sejarah set +H.


40
2017-12-02 16:31



Apakah Anda tahu alasan di balik sintaks? Tampaknya sangat kontra intuitif. Anda akan berpikir Anda mengetik +H untuk mengaktifkan sesuatu dan -H untuk menonaktifkan sesuatu. - PunkyGuy
@PunkyGuy: Saya tidak tahu sejarah (pun intended) di belakangnya, tapi opsi Unix biasanya dimulai dengan tanda hubung (atau minus) dan + hanya kebalikan dari itu. - Dennis Williamson


! adalah karakter khusus untuk bash, digunakan untuk merujuk ke perintah sebelumnya; misalnya,

!rm

akan memanggil kembali dan mengeksekusi perintah terakhir yang dimulai dengan string "rm", dan

!rm:p

akan mengingat tetapi tidak menjalankan perintah terakhir yang dimulai dengan string "rm". bash menginterpretasikan tanda seru di echo "reboot your instance!" sebagai "gantikan disini perintah terakhir yang dimulai dengan karakter segera mengikuti tanda seru", dan menggerutu pada Anda bahwa itu tidak dapat menemukan suatu peristiwa (perintah) dalam sejarah Anda yang dimulai dengan satu kutipan ganda.

Mencoba

echo reboot your instance\!

untuk melindungi (melarikan diri) tanda seru dari bash.


86
2017-12-02 10:49



Ya, tetapi seharusnya terjadi jika saya ingin menggunakan echo -e "beberapa teks $ ENV_VAL beberapa teks lagi \ nReboot sekarang!" ? - Maxim Veksler
Tulis dua pernyataan echo; Anda mendapatkan linefeed secara gratis. - MadHatter
Solusi sederhana adalah menggunakan tanda kutip tunggal dan tanda kutip ganda sekaligus: echo -e "Text \ nReeboot" '!' - mmey
Ini menyebalkan. Jika saya tidak luput dari tanda seru, bash melempar bugar. Jika saya melakukan melarikan diri, backslash termasuk dalam string terakhir. Kenapa kamu melakukan ini, Bash !! (pastebin.com/g4PYv56A) - Hubro
@Hubro dalam keadilan, saya tidak yakin itu semua kesalahan bash. Anda memiliki masalah yang agak rumit dengan menggunakan ruby ​​untuk memberi makan hal-hal untuk bash, dan itu tidak jelas bagi saya apa ruby ​​bagian bermain di stripping atau memperkuat karakter melarikan diri. - MadHatter


Untuk mengatasi masalah asli Anda, coba gunakan tanda kutip tunggal, bukan tanda kutip ganda. Dengan yang terakhir, bash akan mencoba untuk memperluas karakter tertentu sebelum meneruskan hasilnya ke perintah (echo dalam kasus ini). Dengan tanda kutip tunggal, bash melewati seluruh string, tidak berubah.

! digunakan dalam perintah untuk merujuk pada sejarah baris perintah. Lihat: http://tldp.org/LDP/abs/html/abs-guide.html#HISTCOMMANDS untuk satu set lengkap. Dengan contoh di atas, bash sedang mencoba untuk memperluas !" sebagai referensi ke suatu peristiwa sebelum echo mendapat tampilan, maka kesalahan.

Perhatikan bahwa dalam skrip, semua dari perintah sejarah dinonaktifkan, karena hanya masuk akal dalam shell interaktif.

Satu-satunya yang saya gunakan secara teratur, adalah !$. Ini memperluas ke argumen terakhir dari perintah sebelumnya. Ini singkatan yang berguna di beberapa tempat.


22
2017-12-02 11:02



!! untuk mengisi perintah terakhir lengkap yang dimasukkan sangat bermanfaat; terutama, sudo !! atau pfexec !! - jgoldschrafe
Saya juga menemukan sudo dan pfexec sebagai utilitas yang bagus, tetapi tidak perlu terlalu antusias. - LeartS
$_ bekerja di lebih banyak cangkang daripada bash dan itu adalah variabel yang tepat, tidak seperti !$. (dan @LeartS: Saya suka kurangnya emotikon lelucon Anda.;)) - ΤΖΩΤΖΙΟΥ


Taruh ruang di antara! dan "daripada itu akan berhasil.

Tepuk tangan.


5
2017-09-25 07:06



Bisakah Anda menambahkan penjelasan mengapa solusi Anda berfungsi? - 200_success
Ini berfungsi karena Bash hanya memperlakukan! sebagai karakter khusus jika langsung diikuti oleh karakter non-spasi. Namun, itu juga akan menambah kosong ekstra untuk output Anda, sehingga mungkin tidak selalu diinginkan ... - mmey


Iya nih, ! adalah karakter khusus untuk bash, digunakan untuk merujuk ke perintah sebelumnya.

Beberapa cara Anda dapat menangani situasi ini

Berikut ini akan mengeluarkan string seperti apa adanya

echo 'Reboot your instance!'

Berikut ini akan mengeksekusi perintah dan menggabungkan string

echo 'escaping #'" adding `which python` to the string"
echo '#!'`which python`

2
2018-04-25 13:57





Di bash 4.3 tampaknya Anda tidak perlu lagi menggunakan tanda kutip tunggal atau set +H:

$ bash --version
GNU bash, version 4.3.46(1)-release (x86_64-unknown-linux-gnu)
[...]
$ echo "Reboot your instance!"
Reboot your instance!

1
2017-07-12 14:43



Mungkin bug, karena di sini, saya memiliki 4.4.12 dan lagi, saya perlu set +H atau mengutip. Atau kamu punya set +H suatu tempat (seperti di /etc/profile). - Bodo Thiesen
Menggunakan! -Char tidak pada akhir kalimat memverifikasi deteksi acara bash masih berfungsi dengan baik. Versi 4.3.30 ........ $ echo "Periksa kembali kalimatmu! Foo" bash:! Foo: event tidak ditemukan - JohnnyD92


Anda juga bisa menggunakan heredoc:

cat <<EOF
Reboot your instance!
EOF

Ini menjengkelkan dalam kasus ini karena itu bukan satu-liner tetapi untuk perintah yang lebih panjang (seperti menulis skrip bash), itu bekerja dengan baik.


0
2017-07-07 11:41