Comprensione del backtick (`)


35

Sto provando il comando

$ b=5; echo `$b`;
-bash: 5: command not found

ma non stampa 5 come dovrebbe. Cosa mi sto perdendo qui?

Cosa significa `(backquote / backtick) nei comandi? sembra dire che `valuta i comandi all'interno e li sostituisce con l'output.


8
Si noti che i backtick non sono consigliati poiché si perderà la possibilità di effettuare sostituzioni di esecuzione nidificate. Insetad, $ (somecommand) è preferito. Imho migliora la leggibilità.
Tommy,

6
@ Tommy, No, i backtick possono essere nidificati, ma diventa un incubo in fuga, soprattutto quando si fa anche una doppia virgoletta.
Stéphane Chazelas,

Risposte:


52

Il testo tra i backtick viene eseguito e sostituito dall'output del comando (meno i caratteri newline finali, e attenzione che i comportamenti della shell variano quando ci sono caratteri NUL nell'output). Questo si chiama sostituzione dei comandi perché viene sostituito con l'output del comando. Quindi, se si desidera stampare 5, non è possibile utilizzare i backtick, è possibile utilizzare le virgolette, come echo "$b"o semplicemente eliminare qualsiasi citazione e utilizzare echo $b.

Come puoi vedere, dato che $bcontiene 5, quando si utilizza backtick bashsi tenta di eseguire il comando 5e poiché non esiste tale comando, non riesce con un messaggio di errore.

Per capire come funzionano i backtick, prova a eseguire questo:

$ A=`cat /etc/passwd | head -n1`
$ echo "$A"

cat /etc/passwd |head -n1dovrebbe stampare la prima riga del /etc/passwdfile. Ma poiché usiamo i backtick, non lo stampa sulla console. Invece è memorizzato in Avariabile. Puoi fare eco $Aa questo. Si noti che il modo più efficiente di stampare la prima riga sta usando il comando head -n1 /etc/passwdma volevo sottolineare che l'espressione all'interno dei backtick non deve essere semplice.

Quindi, se la prima riga di / etc / passwd è root:x:0:0:root:/root:/bin/bash, il primo comando verrà sostituito dinamicamente da bash a A="root:x:0:0:root:/root:/bin/bash".

Si noti che questa sintassi è della shell Bourne. Citare e scappare diventa rapidamente un incubo, specialmente quando inizi a nidificarli. Ksh ha introdotto l' $(...)alternativa che ora è standardizzata ( POSIX ) e supportata da tutte le shell (anche la shell Bourne di Unix v9). Quindi dovresti usare $(...)invece al giorno d'oggi a meno che tu non abbia bisogno di essere portabile su shell Bourne molto vecchie.

Si noti inoltre che l'output di `...`e $(...)sono soggetti alla suddivisione delle parole e alla generazione del nome del file proprio come l'espansione variabile (in zsh, solo la suddivisione delle parole), quindi generalmente dovrebbero essere citati in contesti di elenco.


1
Ciao @Krzysztof, questo è utile! "dato che $ b contiene 5, bash sta cercando di eseguire il comando 5" è esattamente quello che stavo cercando
coolcric

you can use quotation marks, like echo "$b"=> il "" fa qualcosa di speciale? Sembra echo $bche funzionerebbe altrettanto bene.
Tootsie Rolls

@Anita: In generale le virgolette fanno alcune cose speciali (cambia il modo in cui vengono trattati i caratteri speciali - specialmente gli spazi bianchi) ma in questo caso, possono essere rilasciati senza molti problemi. Questo perché non vengono utilizzati caratteri speciali e il echocomando non si preoccupa del numero di argomenti che riceve, quindi se bha degli spazi all'interno, otterrà più argomenti e li stamperà comunque. Questo potrebbe non essere il caso di altri comandi (specialmente quando la variabile non è impostata), quindi tendo sempre a circondare le variabili tra virgolette.
Krzysztof Adamski l'

sarebbe bello se (POSIX)fosse un collegamento allo standard attuale.
erikbwork,

1
@erikb85: questa nota non è stata aggiunta da me ma l'ho modificata con il link come hai suggerito :)
Krzysztof Adamski

11

Il backtick fa esattamente quello che dici di fare. Hai impostato una variabile su un numero intero. Quando inserisci quella variabile nei backtick, bash proverà ad eseguirla come comando. Dal momento che non è un comando, viene visualizzato l'errore visualizzato.

Quello che vuoi fare è semplicemente:

$ b=5; echo $b

Per capire meglio i bastoncini, confrontalo con:

$ b=5; a=`echo $b`; echo $a
  5

8

Andando passo dopo passo la tua linea dovrebbe spiegarlo.

$ b=5; echo `$b`;
  1. imposta la variabile bsu 5
  2. valuta $b(funziona efficacemente 5)
  3. echoes l'output della valutazione sopra.

Quindi sì, è previsto l'output ottenuto. Stai valutando il contenuto di una variabile, non il comando effettivo che pensavi di essere. Tutto ciò che si inserisce nei backtick viene valutato (eseguito) in una nuova (sotto) shell.


ciao @gertvdijk, grazie per il tuo post! Stavo pensando che `restituisce qualunque cosa rimanga dopo averne valutato il contenuto. Quindi, ho pensato che $ b avrebbe restituito 5 per l'eco per stamparlo
coolcric,
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.