“-Bash:!” Nedir: etkinlik bulunamadı "


114

Bir bash kabuğunun altında aşağıdakini çalıştırmayı deneyin echo "Reboot your instance!"

Kurulumumda:

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

Birisi lütfen "bash olaylarının" ne olduğunu açıklayabilir mi? Bu konsepti daha önce hiç duymamıştım. Ayrıca nasıl "!" Çıkmalıyım? cümlenin sonunda mı?

Yanıtlar:


53

Kullanarak tarih değiştirme özelliğini kapatabilirsiniz set +H.


2
Sözdiziminin arkasındaki nedenleri biliyor musunuz? Gerçekten karşı sezgisel görünüyor. Bir şeyi +Hetkinleştirmek ve bir -Hşeyi devre dışı bırakmak için yazacağınızı düşünürdünüz .
Gavin Ward

7
@PunkyGuy: Arkasındaki geçmişi (amaçlanan) bilmiyorum, ama Unix seçenekleri tipik olarak kısa çizgi (veya eksi) ile başlar ve +bunun tam tersidir.
Dennis Williamson,

105

!bash özel bir karakter, önceki komutlara atıfta bulunmak için kullanılır; Örneğin,

!rm

"rm" ile başlayan son komutu hatırlayacak ve uygulayacaktır.

!rm:p

"rm" ile başlayan son komutu geri çağırır fakat yürütmez. bash, ünlem işaretini echo "reboot your instance!"" burada, ünlem işaretini hemen takip eden karakter (ler) ile başlayan son komutu yerine koy " olarak yorumluyor ve tarihinizde tek bir şeyle başlayan bir olayı (komutu) bulamadığını size söylüyor. çift tırnak.

Deneyin

echo reboot your instance\!

ünlem işaretini bash'den korumak (kaçmak) için.


Evet, ancak echo -e kullanmak istersem "bazı metin $ ENV_VAL biraz daha metin \ nYeni başlat!" ?
Maxim Veksler

1
İki yankı ifadesi yazın; bedavaya lanet olsun.
MadHatter

1
Basit çözüm, tek seferde tek tırnak ve çift tırnak kullanmaktır: echo -e "Text \ nReeboot" '!'
mmey

4
Bu berbat. Ünlem işaretinden kaçmazsam, bas bir form atar. Ben ise bunu ondan kaçmak, ters eğik çizgi nihai dize dahildir. Bunu neden yapıyorsun, Bash !! ( pastebin.com/g4PYv56A )
Hubro

2
@Hubro adalet içinde, bunun bütün bash'ın suçu olduğundan emin değilim. Bir şeyleri ezmek için yakut kullanarak biraz karmaşık meseleleriniz var ve kaçış karakterlerinin soyulmasında ya da güçlendirilmesinde yakutun hangi parçanın oynadığı bana açık değil.
MadHatter

25

Asıl sorununuzu çözmek için çift tırnak yerine tek tırnak kullanmayı deneyin. İkincisi ile bash, sonucu komuta vermeden önce bazı karakterleri genişletmeye çalışacaktır (bu durumda yankı). Tek tırnak işaretleri ile bash tüm dizgiyi değiştirmeden değiştirir.

!komut satırındaki komut satırına atıfta bulunmak için kullanılır. Bkz: http://tldp.org/LDP/abs/html/abs-guide.html#HISTCOMMANDS tam set için. Yukarıdaki örnekte bash, yankıya !"bakmadan önce bir olaya başvuru olarak genişlemeye çalışıyor , bu nedenle hatayı.

Komut dosyalarında, yalnızca etkileşimli bir kabukta mantıklı oldukları için tüm geçmiş komutlarının devre dışı bırakıldığını unutmayın.

Düzenli olarak kullandığım tek şey !$. Bir önceki komutun son argümanına genişler. Yerlerde kullanışlı bir kestirme.


4
!!girilen son komutun tamamını doldurmak oldukça yararlıdır; özellikle, sudo !!veyapfexec !!
jgoldschrafe

2
Ayrıca, sudo ve pfexec'i iyi bir yardımcı program olarak görüyorum, ancak bu kadar hevesli olmanıza gerek yok.
LeartS

$_bash'dan daha fazla kabukta çalışır ve aksine, uygun bir değişkendir !$. (ve @LeartS: Şakalarının ifadelerinin olmamasını sevdim.;))
ΤΖΩΤΖΙΟΥ

7

Sadece arasına bir boşluk koy! ve "işe yarayacağından.

Şerefe.


2
Çözümünüzün neden işe yaradığına dair bir açıklama ekler misiniz?
200_success

2
Bu işe yarıyor çünkü Bash sadece davranıyor! Özel bir karakter olarak doğrudan boşluk içermeyen bir karakter tarafından takip ediliyorsa. Ancak, çıktınıza fazladan bir boşluk da ekler, böylece her zaman istenmeyebilir ...
mmey

2

Evet, ! bash özel bir karakter, önceki komutlara atıfta bulunmak için kullanılır.

Durumu idare etmenin yollarından bazıları

Aşağıdaki dize olduğu gibi çıkacaktır

echo 'Reboot your instance!'

Aşağıdakiler komutu yürütür ve dizeyi birleştirir

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

1

Gelen bash 4.3görünüyor artık tek tırnak veya kullanmak gerekir set +H:

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

Muhtemelen bir hata, çünkü burada 4.4.12 var ve yine yine ihtiyacım var set +Hveya alıntı yapıyorum . Yoksa var set +H(gibi bir yerde /etc/profile).
Bodo Thiesen

Cümlenin sonunda değil! -Char kullanarak bash olay tespiti hala iyi çalıştığını doğrular. Sürüm 4.3.30 ........ $ echo "Cümlenizi tekrar kontrol edin! Foo" bash
:!

0

Ayrıca heredoc kullanabilirsiniz :

cat <<EOF
Reboot your instance!
EOF

Bu durumda can sıkıcı bir durum çünkü tek bir gömlek değil ama daha uzun komutlar için (bash betiği yazmak gibi) harika çalışıyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.