Commenti
Risposta
" Sostituzione del comando " è il nome della funzione del linguaggio della shell che ti permette di eseguire un comando e fare in modo che loutput di quel comando sostituisca ( sostituire) il testo del comando.
Non cè nessunaltra caratteristica del linguaggio della shell che ti permetta di farlo.
Una sostituzione del comando, cioè lintero $(...)
espressione, è sostituito dal suo output, che è luso principale delle sostituzioni di comandi.
Il comando che esegue la sostituzione del comando, viene eseguito in un subshell, il che significa che ha un proprio ambiente che non influenzerà lambiente della shell genitrice.
Non tutte le esecuzioni di subshell sono sostituzioni di comandi ugh (vedi ulteriori esempi alla fine).
Esempio che mostra che una sostituzione di comando viene eseguita in una subshell:
$ s=123 $ echo "hello $( s=world; echo "$s" )" hello world $ echo "$s" 123
Qui, il la variabile s
è impostata sulla stringa 123
. Nella riga successiva, echo
viene richiamato su una stringa contenente il risultato di una sostituzione di comando. La sostituzione del comando imposta s
sulla stringa world
e fa eco a questa stringa. La stringa world
è loutput del comando nella sostituzione del comando e quindi, se è stato eseguito con set -x
, vedremmo che la seconda riga sopra sarebbe stata espansa a echo "hello world"
, che produce hello world
sul terminale:
$ set -x $ echo "hello $( s=world; echo "$s" )" ++ s=world ++ echo world + echo "hello world" hello world
(bash
aggiunge un ulteriore livello di +
prompt a ogni livello di una subshell di sostituzione del comando nelloutput della traccia, altre shell potrebbero non farlo)
Infine, mostriamo che il comando allinterno della sostituzione del comando è stato eseguito nella sua subshell, perché non ha influenzato il valore di s
nella shell chiamante (il valore di s
è ancora 123
, non world
).
Ci sono altre situazioni in cui i comandi vengono eseguiti in subshell, come in
echo "hello" | read message
In bash
, a meno che non imposti lopzione lastpipe
(solo in istanze non interattive), read
viene eseguito in una subshell, il che significa che $message
non verrà modificato nella shell genitore, ovvero eseguendo echo "$message"
dopo il comando precedente verrà visualizzata una stringa vuota (o qualsiasi valore $message
era prima).
Una sostituzione di processo in bash
viene eseguita anche in una subshell:
cat < <( echo "hello world" )
Anche questo è diverso dalla sostituzione di un comando.
Commenti
- Per bash 4.2 in su, se shopt lastpipe è impostato, il controllo del lavoro non è attivo e la pipeline non è in background, lultimo comando non viene eseguito in una subshell.
- Dici: “Non ci sono altre caratteristiche del linguaggio shell che ti consentono di farlo”. Bene, a rischio di spaccarti i capelli, puoi fare
cmd₁ > myfile
/read -r var < myfile
/cmd₂ "$var"
. Se necessario, puoi espanderlo per gestire dati su più righe. - @ G-Man Sì, e puoi anche scrivere un nuovo script di shell su un file ed eseguirlo.Tuttavia, non esistono altre funzionalità che forniscono un modo per sostituire una parte di testo con loutput di un comando.
Risposta
a=$(command)
memorizzerà il valore del risultato di command
nella variabile.
Non cè davvero più niente.
Come nota a margine, credo che:
a=`command`
sia stato deprecato e abbia il stesso significato come sopra.
Commenti
- risultato ecco loutput standard del comando privato di tutta la sua nuova riga finale caratteri (e alcune variazioni tra le shell se loutput non è testo). Tieni presente che
`...`
è la Bourne della sintassi csh mentre$(...)
è la sintassi Korn / POSIX (con`...`
ancora supportato per compatibilità con le versioni precedenti) - @St é phaneChazelas Grazie per le preziose informazioni e sentiti libero di modificare la risposta per includerla.
echo
è un cattivo esempio di sostituzione del comando perché 1) loutput sarebbe stato comunque visualizzato, 2)printf
è più sicuro da usare per i dati variabili. Lesempio potrebbe anche essere scrittodate | sed 's/^/Today is /'
printf
) è inutile. Ho cambiato leggermente la frase, da immediatamente asometime later
, è più accattivante?thedate=$(date)
, seguito daprintf 'The date is %s\n' "$thedate"
.