Per memorizzare l'output di un comando come variabile in sh / ksh / bash, puoi fare entrambe le cose
var=$(command)
o
var=`command`
Qual è la differenza tra i due metodi?
Per memorizzare l'output di un comando come variabile in sh / ksh / bash, puoi fare entrambe le cose
var=$(command)
o
var=`command`
Qual è la differenza tra i due metodi?
Risposte:
I backtick / segni di grave sono stati deprecati a favore della $()
sostituzione del comando perché $()
possono facilmente nidificarsi dentro di sé come in $(echo foo$(echo bar))
. Esistono altre differenze come il modo in cui le barre rovesciate vengono analizzate nella versione backtick / gravemark, ecc.
Vedi BashFAQ / 082 per diversi motivi per preferire sempre la sintassi $ (...).
Vedi anche le specifiche POSIX per informazioni dettagliate sulle varie differenze.
$(...)
- li nota solo come alternative.
"the backquoted variety of command substitution is not recommended"
che è solo un modo lungo e tortuoso di dire IMHO deprecato
$(...)
come metodo alternativo. Non sono noti bug di implementazione con backtick, ma ci sono molti bug di implementazione noti $(...)
. Pertanto, per problemi di portabilità, si consiglia di utilizzare i backtick per le chiamate non nidificate. $(...)
ha bisogno di un parser ricorsivo ma questo non è stato usato con ksh86 che ha introdotto la funzione. Controllare in-ulm.de/~mascheck/various/cmd-subst per un elenco delle implementazioni corrette. Una shell conforme deve supportare tutti i casi tranne il caso D.2.
deprecated
, ad esempio, l'uso waitpid()
che impedisce di vedere tutti i 32 bit dal exit()
parametro, ma tutte le shell tranne la recente Bourne Shell usano ancora waitpid()
invece della waitid()
chiamata che è ora disponibile da 26 anni
$()
, che è più spiegato in questa parte della documentazione . Le differenze non riguardano solo la nidificazione.
Si comportano allo stesso modo. La differenza è sintattica: è più facile nidificare $()
di ``
:
listing=$(ls -l $(cat filenames.txt))
vs.
listing=`ls -l \`cat filenames.txt\``
echo $(echo \$abc)
Non è la stessa echo `echo \$abc`
- esistono anche differenze per $(echo \`)
e $(echo \\)
echo foo `#comment`
vs echo foo $(#comment)
. Il secondo non funziona. (Utilizzato per commentare in un comando multilinea.)
Luglio 2014: il commit f25f5e6 (di Elia Pinto ( devzero2000
) , aprile 2014, Git 2.0) aggiunge al problema della nidificazione:
Il modulo retroquisito è il metodo tradizionale per la sostituzione dei comandi ed è supportato da POSIX.
Tuttavia, tutti gli usi tranne quelli più semplici si complicano rapidamente.
In particolare, le sostituzioni di comandi incorporate e / o l'uso di virgolette doppie richiedono un'attenta evasione con il carattere barra rovesciata .
Ecco perché la git / Documentation / CodingGuidelines menziona:
Preferiamo la
$( ... )
sostituzione dei comandi; a differenza di ``, nidifica correttamente .
Avrebbe dovuto essere il modo in cui Bourne l'ha scritto fin dal primo giorno, ma sfortunatamente non lo è.
Questo è il motivo
`echo `foo``
per cui non funzionerà in generale a causa dell'ambiguità intrinseca perché ognuno``
può aprirsi o chiudersi.
Potrebbe funzionare per casi speciali a causa di fortuna o funzionalità speciali.
Aggiornamento gennaio 2016: Git 2.8 (marzo 2016) elimina completamente i backtick.
Vedi commit ec1b763 , commit 9c10377 , commettere c7b793a , commettere 80a6b3f , commettere 9375dcf , commettere e74ef60 , commettere 27fe43e , commettere 2525c51 , commettere becd67f , commettere a5c98ac , commettere 8c311f9 , commettere 57da049 , commettere 1d9e86f , commettere 78ba28d , commettere efa639f , commettere 1be2fa0 , commettono 38e9476 , commit 8823d2f , commit 32858a0 , commit cd914d8(12 gennaio 2016) di Elia Pinto (devzero2000
) .
(Unita da Junio C Hamano - gitster
- in commit e572fef , 22 gen 2016)
Da Git 2.8 in poi, è tutto $(...)
, non di più `...`
.
$()
è anche specificato POSIX - una citazione che descrive i backtick come "supportati da POSIX" in modo tale da implicare che ciò sia unico per loro è fuorviante. È solo (Bourne pre-POSIX dell'era degli anni '70) che i backtick sono l'unica sintassi supportata.
Quando viene utilizzato il vecchio modulo di back-tick, backslash mantiene il suo significato letterale tranne quando seguito da $, `o \. Il primo segno di spunta non preceduto da una barra rovesciata termina la sostituzione del comando.
Quando si utilizza il più recente $(command)
modulo , tutti i caratteri tra parentesi formano il comando; nessuno è trattato in modo speciale.
Entrambi i moduli possono essere nidificati, ma la varietà back-tick richiede il seguente modulo.
`echo \`foo\``
Al contrario di:
$(echo $(foo))
$()
versione sono conformi a POSIX.
C'è poca differenza, ad eccezione dei caratteri senza caratteri di escape che è possibile utilizzare all'interno del comando. Puoi anche inserire i comandi `...` all'interno di $ (...) (e viceversa) per una sostituzione dei comandi più complessa a due livelli.
Esiste un'interpretazione leggermente diversa del carattere / operatore della barra rovesciata. Tra le altre cose, quando si annidano i comandi di sostituzione `...` , è necessario sfuggire ai caratteri interni ` con \, mentre con la sottostazione $ () capisce automaticamente l'annidamento.