GNU/Linux >> Linux Esercitazione >  >> Linux

Espansione di stringhe tra quotate e non quotate?

  1. for i in $(xrandr); do echo "$i" ; done
  2. for i in "$(xrandr)"; do echo "$i"; done
  3. for i in "$(xrandr)"; do echo $i; done

Capisco perché 1 differisce da 2. Ma perché 3 fornisce un output diverso da 2? Si prega di spiegare anche l'output. Come funzionano le virgolette sulle nuove righe?

Risposta accettata:

Una variabile senza virgolette (come in $var ) o la sostituzione del comando (come in $(cmd) o `cmd` ) è il split+glob operatore in shell tipo Bourne.

Cioè, il loro contenuto è suddiviso in base al valore corrente di $IFS variabile speciale (che per impostazione predefinita contiene i caratteri spazio, tabulazione e nuova riga)

E poi ogni parola risultante da quella divisione è soggetta a generazione di nomi di file (noto anche come globbing o espansione del nome file ), ovvero sono considerati modelli e vengono espansi all'elenco di file che corrispondono a tale modello.

Quindi in for i in $(xrandr) , il $(xrandr) , poiché non è racchiuso tra virgolette, è suddiviso in sequenze di caratteri spazio, tabulazione e nuova riga. E ogni parola risultante da quella divisione viene verificata per i nomi dei file corrispondenti (o lasciata così com'è se non corrispondono a nessun file) e for li scorre tutti.

In for i in "$(xrandr)" , non utilizziamo l'operatore split+glob come sostituzione di comando è quotato, quindi c'è un passaggio nel ciclo su uno valore:l'output di xrandr (senza i caratteri di nuova riga finali che comandano la sostituzione strisce).

Tuttavia in echo $i , $i è di nuovo senza virgolette, quindi di nuovo il contenuto di $i è diviso e soggetto a generazione di nomi di file e quelli vengono passati come argomenti separati a echo comando (e echo restituisce i suoi argomenti separati da spazi).

Quindi lezione appresa:

  • se non vuoi dividere le parole o generazione di nomi di file , cita sempre espansioni di variabili e sostituzioni di comandi
  • se vuoi dividere le parole o generazione di nomi di file , lasciali senza virgolette ma imposta $IFS di conseguenza e/o abilitare o disabilitare la generazione del nome del file, se necessario (set -f , set +f ).

Tipicamente, nel tuo esempio sopra, se vuoi scorrere l'elenco vuoto di parole separate nell'output di xrandr , dovresti:

  • lascia $IFS al suo valore predefinito (o deselezionalo) per dividerlo in spazi vuoti
  • Usa set -f per disabilitare la generazione del nome file a meno che tu non sia sicuro che xrandr non genera mai alcun * o ? o [ caratteri (che sono caratteri jolly utilizzati nei modelli di generazione dei nomi di file)
Correlati:Db2:trova la stringa di connessione per un database DB2?

E poi usa solo l'operatore split+glob (lascia solo la sostituzione del comando o l'espansione della variabile senza virgolette) nel in parte del for ciclo:

set -f; unset -v IFS
for i in $(xrandr); do whatever with "$i"; done

Se vuoi scorrere le linee (non vuote). del xrandr output, dovresti impostare $IFS al carattere di nuova riga:

IFS='
'

Linux
  1. Espansione e variabili Bash Brace?

  2. Sostituzione di stringhe usando un dizionario?

  3. `~#` è un'espansione di Tilde di Bash?

  4. Come dividere una stringa nello script Bash

  5. in_addr_t alla stringa

Bash concatena le stringhe

Come verificare se una stringa contiene una sottostringa in Bash

Sostituzione di String in Bash

Bash Scripting – Manipolazione di stringhe

limite di lunghezza della stringa della funzione system()

Come aggiungo una variabile a questo comando curl?