GNU/Linux >> Linux Esercitazione >  >> Linux

Citando entro $(sostituzione comando) in Bash?

Nel mio ambiente Bash utilizzo variabili contenenti spazi e utilizzo queste variabili all'interno della sostituzione dei comandi.

Qual è il modo corretto per quotare le mie variabili? E come devo farlo se questi sono nidificati?

DIRNAME=$(dirname "$FILE")

o cito al di fuori della sostituzione?

DIRNAME="$(dirname $FILE)"

o entrambi?

DIRNAME="$(dirname "$FILE")"

o uso i backtick?

DIRNAME=`dirname "$FILE"`

Qual è il modo giusto per farlo? E come posso verificare facilmente se le virgolette sono impostate correttamente?

Risposta accettata:

In ordine dal peggiore al migliore:

  • DIRNAME="$(dirname $FILE)" non farà quello che vuoi se $FILE contiene spazi bianchi (o qualsiasi altro carattere $IFS contiene attualmente) o caratteri glob [?* .
  • DIRNAME=`dirname "$FILE"` è tecnicamente corretto, ma i backtick non sono consigliati per l'espansione dei comandi a causa della maggiore complessità durante l'annidamento e dell'elaborazione della barra rovesciata aggiuntiva che avviene al loro interno.
  • DIRNAME=$(dirname "$FILE") è corretto, ma solo perché si tratta di un'assegnazione a una variabile scalare (non array). Se usi la sostituzione del comando in qualsiasi altro contesto, come export DIRNAME=$(dirname "$FILE") o du $(dirname -- "$FILE") , la mancanza di virgolette causerà problemi se il risultato dell'espansione contiene spazi bianchi o caratteri glob.
  • DIRNAME="$(dirname "$FILE")" (tranne per il -- mancante , vedi sotto) è il modo consigliato. Puoi sostituire DIRNAME= con un comando e uno spazio senza modificare nient'altro, e dirname riceve la stringa corretta.

Per migliorare ulteriormente:

  • DIRNAME="$(dirname -- "$FILE")" funziona se $FILE inizia con un trattino.
  • DIRNAME="$(dirname -- "$FILE" && printf x)" && DIRNAME="${DIRNAME%?x}" || exit funziona anche se $FILE 's dirname termina con una nuova riga, poiché $() taglia le nuove righe alla fine dell'output, sia quella aggiunta da dirname e quelli che potrebbero far parte dei dati effettivi.

Puoi annidare le espansioni dei comandi quanto vuoi. Con $() crei sempre un nuovo contesto di quotazione, quindi puoi fare cose come questa:

foo "$(bar "$(baz "$(ban "bla")")")"

Tu non voglio provarlo con i backtick.


Linux
  1. Il comando "eval" in Bash?

  2. Sostituzione dei comandi usando “?

  3. a partire da apachectl bash

  4. comando di esportazione bash

  5. Codice di uscita dall'assegnazione della variabile alla sostituzione dei comandi in Bash

Comando della cronologia in Linux (Cronologia di Bash)

Comando di uscita Bash e codici di uscita

Comando Bash printf

Script Bash(II)

Scripting Bash(III)

Utilizzo del comando Linux Dirname negli script Bash