Vraag Wat is "-bash:!": Evenement niet gevonden "


Probeer het volgende uit te voeren onder een bash-shell echo "Reboot your instance!"

Op mijn installatie:

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

Kan iemand uitleggen wat 'bash-evenementen' zijn? Ik heb dit concept nog nooit gehoord. Ook, hoe moet ik output "!" aan het einde van de zin?


88
2017-12-02 10:45


oorsprong




antwoorden:


Je kunt geschiedenisvervanging uitschakelen met set +H.


40
2017-12-02 16:31



Kent u de redenering achter de syntaxis? Het lijkt echt contra-intuïtief. Je zou denken dat je zou typen +H om iets in te schakelen en -H om iets uit te schakelen. - PunkyGuy
@PunkyGuy: Ik ken de geschiedenis (woordspeling bedoeld) er achter niet, maar Unix-opties beginnen meestal met een koppelteken (of minteken) en + is gewoon het tegenovergestelde daarvan. - Dennis Williamson


! is een speciaal teken om te bashen, het wordt gebruikt om te verwijzen naar eerdere commando's; bv

!rm

zal het laatste commando dat begon met de string "rm" oproepen en uitvoeren, en

!rm:p

zal het laatste commando dat begon met de string "rm" maar niet uitvoeren. bash interpreteert het uitroepteken in echo "reboot your instance!" zoals "vervang hier de laatste opdracht die begon met het karakter (de tekens) onmiddellijk na het uitroepteken", en gromt tegen je dat het geen evenement (commando) in je geschiedenis kan vinden dat begon met een enkel dubbel aanhalingsteken.

Proberen

echo reboot your instance\!

beschermen (ontsnappen) aan het uitroepteken van bash.


86
2017-12-02 10:49



Ja, maar zou moeten gebeuren als ik echo -e "wat tekst $ ENV_VAL wat meer tekst wil gebruiken \ nReboot nu!" ? - Maxim Veksler
Schrijf twee echo-instructies; je krijgt de linefeed gratis. - MadHatter
Eenvoudige oplossing is om enkele aanhalingstekens en dubbele aanhalingstekens tegelijk te gebruiken: echo -e "Tekst \ n Herstellen" '!' - mmey
Dit is rotzooi. Als ik niet aan het uitroepteken ontsnap, gooit bash een aanval. Als ik do ontsnappen, de backslash is opgenomen in de laatste reeks. Waarom doe je dit, Bash !! (pastebin.com/g4PYv56A) - Hubro
@Hubro in alle eerlijkheid, ik weet niet of dat allemaal de schuld van bash is. Je hebt wat gecompliceerde zaken gedaan door robijn te gebruiken om dingen te bashen, en het is mij niet duidelijk welk deel robijn speelt bij het strippen of versterken van ontsnappingspersonages. - MadHatter


Gebruik enkele aanhalingstekens in plaats van dubbele aanhalingstekens om uw oorspronkelijke probleem op te lossen. Met de laatste zal bash proberen om bepaalde karakters uit te breiden voordat het resultaat aan het commando wordt doorgegeven (echo in dit geval). Met enkele aanhalingstekens geeft bash de hele reeks door, ongewijzigd.

! wordt gebruikt in opdrachten om naar de geschiedenis van de opdrachtregel te verwijzen. Zien: http://tldp.org/LDP/abs/html/abs-guide.html#HISTCOMMANDS voor een volledige set. Met het bovenstaande voorbeeld probeert bash uit te breiden !" als een verwijzing naar een gebeurtenis voordat de echo erin kijkt, vandaar de fout.

Merk op dat in scripts, allemaal van de geschiedenisopdrachten zijn uitgeschakeld, omdat ze alleen zinvol zijn in een interactieve shell.

De enige die ik regelmatig gebruik, is !$. Het wordt uitgebreid tot het laatste argument van het vorige commando. Het is op plaatsen een nuttige steno.


22
2017-12-02 11:02



!! het invullen van de volledige laatst ingevoerde opdracht is opmerkelijk nuttig; in het bijzonder, sudo !! of pfexec !! - jgoldschrafe
Ik vind ook sudo en pfexec goede hulpprogramma's, maar je hoeft niet zo enthousiast te zijn. - LeartS
$_ werkt in meer shells dan bash en het is een echte variabele, in tegenstelling tot !$. (en @LeartS: Ik vond het emoticongebrek van je grap erg leuk;;)) - ΤΖΩΤΖΙΟΥ


Plaats gewoon een spatie tussen! en "dan werkt het.

Proost.


5
2017-09-25 07:06



Kunt u een uitleg toevoegen waarom uw oplossing werkt? - 200_success
Dit werkt omdat Bash alleen behandelt! als een speciaal teken als het direct gevolgd wordt door een niet-spatie karakters. Het voegt echter ook een extra spatie toe aan uw uitvoer, dus dat is misschien niet altijd gewenst ... - mmey


Ja, ! is een speciaal teken om te bash, het wordt gebruikt om te verwijzen naar eerdere commando's.

Weinig manieren om met de situatie om te gaan

Het volgende zal de string uitvoeren zoals die is

echo 'Reboot your instance!'

Het volgende voert de opdracht uit en voegt de reeks samen

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

2
2018-04-25 13:57





In bash 4.3 het lijkt erop dat u niet langer enkele aanhalingstekens hoeft te gebruiken of 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



Waarschijnlijk een bug, want hier heb ik 4.4.12 en nog eens, ik heb het nodig set +H of citeren. Of je hebt set +H ergens (zoals in /etc/profile). - Bodo Thiesen
Met behulp van! -Char niet aan het einde van de zin verifieert de gebeurtenisdetectie van bash nog steeds prima. Versie is 4.3.30 ........ $ echo "Controleer je zin opnieuw! Foo" bash:! Foo: evenement niet gevonden - JohnnyD92


U kunt ook een heredoc:

cat <<EOF
Reboot your instance!
EOF

Het is vervelend in dit geval omdat het geen one-liner is, maar voor langere opdrachten (zoals het schrijven van een bash-script) werkt het prima.


0
2017-07-07 11:41