GNU/Linux >> Linux Esercitazione >  >> Linux

È necessario citare le sostituzioni dei comandi quando si assegna l'output a una variabile?

Questa domanda ha già una risposta qui :Quando è necessaria la doppia virgoletta?

(1 risposta)
Chiusa 4 anni fa.

Tendo a citare le sostituzioni dei comandi come mostrato di seguito anche quando assegno il loro output a una variabile:

var="$(command)"

Ma è davvero necessario? Quando si rompe? La risposta accettata qui afferma:

DIRNAME="$(dirname $FILE)" non farà quello che vuoi se $FILE contiene spazi bianchi o caratteri glob [?*.

Il collegamento punta alla fantastica pagina di Grey Cat Wiki sulle citazioni, ma quella pagina non menziona specificamente le sostituzioni dei comandi di citazione. E citando la variabile è chiaramente necessario, citare la sostituzione del comando in sé non sembra esserlo.

Tuttavia, lo stesso post si conclude con:

DIRNAME="$(dirname "$FILE")" è il modo consigliato. Puoi sostituire DIRNAME=con un comando e uno spazio senza modificare nient'altro e dirname riceve la stringa corretta.

Che è quello che ho sempre pensato anch'io e ho spesso ocreto post qui che non lo citavano. Tuttavia, la pagina wiki collegata sopra afferma anche che:

Ci sono alcuni casi in cui le virgolette doppie possono essere tranquillamente omesse:

A destra di un semplice compito. Puoi scrivere foo=$bar senza virgolette. Questo è conforme a POSIX.

[. . . ]

Mentre var=$(command) non è proprio un compito “semplice”, tuttavia non sono riuscito a trovare un caso in cui le virgolette fossero effettivamente necessarie:

$ var=$(echo "foo bar baz")  ## whitespace works
$  echo "$var"
foo bar baz

$ var=$(printf "foonbar * baz") ## so do globbing characters
$ echo "$var"
foo
bar * baz

$ var1="foonbar * baz"
$ var=$(printf "$var1")  ## printing a variable doesn't make any difference
$ echo "$var" 
foo
bar * baz

$ var=$(printf '%sn' "$var1")
$ echo "$var"
foonbar * baz

$ var=$(printf -- '-e %sn' "$var1") ## strings starting with - also work
$ echo "$var"
-e foonbar * baz

Ovviamente, le virgolette sono assolutamente necessarie se la sostituzione del comando viene utilizzata direttamente per cose come command1 "$(command2)" , ma non sembra essere così quando si assegna a una variabile.

Allora, cosa mi sto perdendo? Le citazioni sono mai necessarie? Quale caso d'angolo citerà una sostituzione di comando quando si assegna il suo valore di ritorno a una variabile proteggerti da? Oppure va sempre bene non citare una sostituzione di comando se è il lato destro di un'operazione di assegnazione di variabili?

Risposta accettata:

Come riferimento, il manuale di Bash è chiaro su questo:

Una variabile può essere assegnata da un'istruzione della forma

name=[value]

Se value non viene fornito, alla variabile viene assegnata la stringa nulla. Tutti i valori subiscono l'espansione della tilde, l'espansione dei parametri e delle variabili, la sostituzione dei comandi, l'espansione aritmetica e la rimozione delle virgolette (dettagliata di seguito). […] La divisione delle parole non viene eseguita , ad eccezione di "[email protetta]" come spiegato di seguito. L'espansione del nome file non viene eseguita.

Nessuna divisione delle parole, nessuna espansione del nome del file, quindi nessuna necessità di virgolette.

Correlati:strumento da riga di comando PostgreSQL psql e SET CONSTRAINTS DIFFERITI?

Per quanto riguarda POSIX, sezione 2.9.1 Comandi semplici:

2. Le parole che non sono assegnazioni variabili o reindirizzamenti sono espanse. Se rimangono dei campi dopo la loro espansione Se rimangono dei campi dopo la loro espansione, il primo campo è considerato il nome del comando ei campi rimanenti sono gli argomenti per il comando.
[…]
4. Ogni assegnazione di variabile deve essere ampliato per l'espansione della tilde, l'espansione dei parametri, la sostituzione dei comandi, l'espansione aritmetica e la rimozione delle virgolette prima di assegnare il valore.

Non sono sicuro se questo dovrebbe essere interpretato nel senso che la suddivisione del campo avviene solo per le espansioni eseguite al passaggio 2? Il passaggio 4 non menzionare la suddivisione dei campi, anche se la sezione sulla suddivisione dei campi non menziona anche le assegnazioni di variabili come eccezione alla produzione di più campi.


Linux
  1. Come assegnare l'output di un comando a una variabile di shell?

  2. Memorizzazione dell'output del comando nella variabile Shell?

  3. Come impostare una variabile uguale all'output di un comando in Grub2?

  4. Come nascondere l'output del terminale durante l'esecuzione di un comando?

  5. Esempi di comandi temporali di Linux

Come assegnare l'output di un comando Linux a una variabile

Ccat:colora l'output del comando Cat

Forza gli utenti a utilizzare la password di root anziché la propria password quando utilizzano il comando Sudo

Esempi di comandi echo Linux

Tutte le nuove righe vengono rimosse quando si salva l'output cat in una variabile

Come preservare le interruzioni di riga durante la memorizzazione dell'output del comando in una variabile?