In bash, come posso evitare un punto esclamativo?


183

Voglio fare qualcosa del genere bzr commit -m "It works!". Posso in qualche modo sfuggire al punto esclamativo facendo bzr commit -m "It works\!". Tuttavia, il mio messaggio di commit include la barra rovesciata. Come posso evitare il punto esclamativo, ignorando ancora la barra rovesciata?


1
Anche fare bzr commit -m "It works"!lavori.
kba,

1
Come ho notato prima, il comando che hai inserito funziona davvero da solo :)bzr commit -m "It works!"
h4unt3r

Un caso ancora più stravaganti con le citazioni annidate: stackoverflow.com/questions/22125658/...
Ciro Santilli新疆改造中心法轮功六四事件

1
Sebbene la risposta accettata sia una buona soluzione ai tuoi problemi di commit, ritengo che non sia una risposta al problema reale: l' espansione della cronologia di Bash . Per favore, considera di accettare la risposta di Dennis?
Arjan,

Risposte:


153

Dal momento che non si dipende da bash per espandere le variabili nel messaggio di commit, è possibile utilizzare invece virgolette singole. Le stringhe tra virgolette singole non sono espanse da bash.

bzr commit -m 'This does work!' 

24
Poiché la domanda era "Come posso evitare un punto esclamativo?" e non "Come non espandere un punto esclamativo?" Non credo sia valido. Ci sono alcune volte (come quando si passano apostrofi e punti esclamativi nella stessa riga di comando) che questo non funziona. La risposta che segue funziona molto meglio per fare ciò di cui molte persone hanno bisogno.
Jann,

7
@Jann: hai ragione al 100% su questo, ma penso che il problema sia qui quello con così tante domande su superutente: rispondiamo alla domanda al punto o aiutiamo le persone a risolvere il loro problema specifico. Penso che entrambi i modi possano essere utili, e questo cercava aiuto su un problema specifico.
Benjamin Bannier,

touché! Questo era un problema specifico. Tendo solo a desiderare una risposta alle mie domande per poter essere utilizzato in molte situazioni. pS: Il motivo per cui ho anche menzionato questo era che dovevo passare sia un apostrofo che un punto esclamativo a un programma perl e avevo bisogno della soluzione di seguito. :)
Jann,

Sono d'accordo con Benjamin e Jann ma ho espresso un voto negativo. Il titolo della domanda è indicizzato dai motori di ricerca ed è così che sono venuto qui e probabilmente la maggior parte degli utenti viene qui. Ecco perché credo sia importante che la vera domanda rifletta il problema che sta dietro. In altri forum si consiglia alle persone (quasi costrette) di chiedere esattamente cosa cercano. Rispondere a domande scarsamente espresse supporta la sciattezza e questa è la ragione esatta del mio voto qui. Come compromesso / soluzione, il mio suggerimento è di aiutare ad adattare l'intestazione in modo che rifletta il problema reale.
ChristophK,

153

Ecco un altro metodo se vuoi virgolette doppie e l'esclamazione:

echo "It's broken"'!'

Funziona anche se !non si trova alla fine della riga.

Per esempio:

echo "hello there"'!'" and goodbye"

Bonus: una tecnica simile può essere usata per sfuggire a qualsiasi testo in Sh o Bash (con l'aiuto di sed): vedi la prima opzione in questa risposta . Inoltre, se hai bash-completioninstallato, probabilmente hai già la quote()funzione disponibile.


4
Bel consiglio, JWD. Non mi rendevo conto che le stringhe di bash potevano essere concatenate semplicemente omettendo spazi bianchi tra di loro.
Alan H.,

In realtà se il punto esclamativo si trova alla fine della stringa, sei in chiaro echo "Happy birthday!"funzionerà come previsto, altrimenti puoi evitarlo con una barra rovesciata, ma la barra rovesciata verrà stampata e XD Bash non è per i deboli di cuore :)
h4unt3r,

@ h4unt3r: Strano, non è la mia esperienza. Per me, echo "Happy Birthday!"genera 2 righe. Il primo è echo "Happy birthday"(nessuna esclamazione) e il secondo è "Buon compleanno" (di nuovo, nessuna esclamazione). L'espansione della cronologia è attivata quando si esegue questo test?
jwd,

@jwd che versione di bash stai usando? Ho sempre la sua espansione attiva. Ne hai usati accidentalmente due !! per il tuo test?
h4unt3r,

@ h4unt3r:, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)sicuramente ne !viene utilizzato solo uno . Ho histexpandpresente in $SHELLOPTS. Tuttavia, ho appena provato il rilascio 4.3.18 (2) su un'altra macchina, e si comporta come descritto. Immagino che sia stato corretto un bug.
jwd

66

Disattiva l' espansione della cronologia :

set +H

o

set +o histexpand

Puoi aggiungere uno di questi comandi al tuo ~/.bashrcse di solito non usi l'espansione della cronologia.

Bash 4.3 ha aggiunto un caso speciale :

anche il carattere di espansione della cronologia viene trattato come citato se precede immediatamente la virgoletta doppia di chiusura in una stringa tra virgolette doppie


Grazie - questo ha funzionato, ma ho dovuto fare set +o histexpand, non è set -o histexpand. Potresti modificare la tua risposta per risolvere questo problema?
Matteo,

Oops, refuso, scusa. Fisso.
Dennis Williamson,

eccellente! cercavo questo per ETÀ .... grazie vm! come fuga non funzionerà ... Non voglio usare anche virgolette singole ... Aggiungerò questo al mio grazie .bashrc!!, mai usato !negli script e per niente !! è sempre stato preoccupante ...
Aquarius Power il

È fantastico! echo "@AquariusPower!"
joehanna,

12

Usa virgolette singole (') invece di virgolette doppie ("). Le virgolette singole disattivano tutte le interpretazioni delle cose in esse contenute, mentre le virgolette doppie ne disattivano solo alcune.

bzr commit -m 'It works!'

4

Ho appena trovato un altro modo, che funzionerà almeno con le echostringhe (frasi) che si desidera punteggiare con un punto esclamativo. Esegue un end-run, più o meno, attorno a Bash histexpand e richiede solo un po 'più di tempo per codificare.

L'esagono per un punto esclamativo, come elencato su http://www.ascii-code.com/ , è 21, quindi se metti \x21alla fine della tua stringa echo -e $foo, crea il $foosuo eco espanso [ie, foo=$(echo -e "$foo")], quello che quando echo $foola stringa è di nuovo con un !alla fine. E nessuna commutazione histexpand neanche.

Funziona di sicuro in Bash 4+. Versioni precedenti, ymmv.


Hmmm non funziona per me.
lzap,

Non capisco cosa stai dicendo sull'eco stesso. 'echo -e' e 'printf' interpretano i codici ottali, esadecimali e Unicode con escape. Nei casi in cui si utilizza uno di questi, è possibile utilizzare "\ 041" (l'ottale per "!") O "\ x21" (esadecimale) per sostituire il punto esclamativo. Ad esempio: printf "OMG\041". Se stai costruendo una stringa tra virgolette doppie da qualche parte che non è echo o printf, come la stringa di commit OP richiesta, puoi incorporare $(echo -e "\041")la stringa in cui dovrebbe essere il punto esclamativo. Come questo: bzr commit -m "This is a great commit$(echo -e "\041")".
Todd Walton,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.