Espansione di una variabile shell ed effetto di glob e divisione su di essa


18

Questo post contiene in realtà due domande separate, ma penso che raggrupparle insieme darà un po 'più di contesto. Ho affrontato questa domanda sulle virgolette attorno alle variabili ma non capisco bene cosa significhi l' espansione delle variabili . Quindi la mia prima domanda è:

  1. Che cos'è l' espansione variabile in unix / linux?

Una seconda parte della mia domanda riguarda i seguenti termini:

  1. glob
  2. Diviso

Che cosa significa quanto sopra e in che modo influenzano l'espansione variabile? La risposta alla domanda originale menziona quanto segue:

Pensa all'assenza di virgolette (nei contesti di elenco) come l'operatore split + glob.

Come se echo $ test fosse echo glob (split ("$ test")).

Non sono riuscito a trovare alcuna risposta che affronti direttamente il concetto di globbing e scissione, ma piuttosto usa questi termini direttamente per rispondere ad altre domande come questa recente .


Risposte:


15

Espansione delle variabili (il termine standard è espansione dei parametri , e talvolta viene anche chiamato sostituzione delle variabili ) in pratica significa sostituire la variabile con il suo valore. Più precisamente, significa sostituire il $VARIABLEcostrutto (o ${VARIABLE}o ${VARIABLE#TEXT}altri costrutti) con qualche altro testo che è costruito dal valore della variabile. Questo altro testo è l'espansione della variabile.

Il processo di espansione procede come segue. (Discuto solo il caso comune, alcune impostazioni ed estensioni della shell modificano il comportamento.)

  1. Prendi il valore della variabile, che è una stringa. Se la variabile non è definita, utilizzare la stringa vuota.
  2. Se il costrutto include una trasformazione, applicarla. Ad esempio, se il costrutto è ${VARIABLE#TEXT}e il valore della variabile inizia con TEXT, rimuovi TEXTdall'inizio del valore.
  3. Se il contesto richiede una sola parola (ad esempio tra virgolette doppie, o nella parte destra di un compito o all'interno di un documento qui), fermati qui. Altrimenti continua con i passi successivi.
  4. Dividi il valore in parole separate in ogni sequenza di spazi bianchi. (La variabile IFSpuò essere modificata per dividere in caratteri diversi dallo spazio.) Il risultato non è quindi più una stringa, ma un elenco di stringhe. Questo elenco può essere vuoto se il valore conteneva solo spazi bianchi.
  5. Tratta ogni elemento dell'elenco come un modello jolly di nome file, ovvero un glob . Se il modello corrisponde ad alcuni file, viene sostituito dall'elenco dei nomi file corrispondenti, altrimenti viene lasciato solo.

Ad esempio, si supponga che la variabile foocontiene a* b* c*e la directory corrente contiene i file bar, baze paz. Quindi ${foo#??}viene espanso come segue:

  1. Il valore della variabile è la stringa di 8 caratteri a* b* c*.
  2. #??significa rimuovere i primi due caratteri, risultando nella stringa di 6 caratteri  b* c*(con uno spazio iniziale).
  3. Se l'espansione si trova in un contesto di elenco (ovvero non tra virgolette doppie o altri contesti simili), continua.
  4. Dividi la stringa in parole delimitate da spazi bianchi, ottenendo un elenco di due stringhe: b*e c*.
  5. La stringa b*, interpretata come un modello, corrisponde a due file: bare baz. La stringa c*non corrisponde a nessun file, quindi viene lasciata sola. Il risultato è una lista di tre stringhe: bar, baz, c*.

Ad esempio echo ${foo#??}stampa bar baz c*(il comando echounisce i suoi argomenti con uno spazio in mezzo).

Per maggiori dettagli, vedi:


2
Si noti che si chiama l'espansione di parametro perché si applica alle variabili ( $var) e altri tipi di parametri come $1, $#, $?, $-...
Stéphane Chazelas

12

glob / split

Prenderò prima il glob / split. @ La risposta di Stephane a cui ti sei collegato sta usando quei termini in senso generale. Non sono comandi reali o cose del genere, solo operazioni pseudo.

L' split("$test")avrebbe diviso il contenuto di "$ test" sopra un "allineamento" di elementi.

Il glob(...)impiegherebbe poi cura per espandere qualsiasi di questi elementi contenenti caratteri shell glob come *o intervalli [1-2].

Esempio

Supponiamo che la nostra stringa $testsia la seguente.

$ test="afile[1-2] afile[3-5]"

Diciamo anche che abbiamo una directory con alcuni file al suo interno.

$ ls -1
afile1
afile2
afile3
afile4
afile5

Ora, se proviamo a fare eco senza virgolette, dovresti notare che la nostra stringa si è divisa in spazi e quindi tutti i personaggi globbing si espandono.

$ echo $test
afile1 afile2 afile3 afile4 afile5

Tuttavia, se dovessimo citare la variabile quando l'abbiamo passata come argomento echo, otterremmo la stringa letterale originale.

$ echo "$test"
afile[1-2] afile[3-5]

espansione variabile

Il termine espansione variabile intende indicare l'operazione di base che la shell sta eseguendo come parte delle sue operazioni di base. La shell è responsabile dell'analisi dell'input e quindi dell'esecuzione di questo input una volta ritenuto sintatticamente corretto.

Nel nostro esempio precedente. Quando la variabile è $teststata presentata a echonon quotata, dicevamo alla shell di andare avanti e dividere quegli argomenti e poi globarli.

Quando è stato citato, essenzialmente disabilitavamo quella funzione con qualsiasi variabile che avessimo racchiusa tra virgolette doppie.

Esempio

Ecco alcuni esempi aggiuntivi di globbing e divisione.

glob / split avviene automaticamente

$ echo file{1..3}
file1 file2 file3

$ echo file{1..3} dir{a..b}
file1 file2 file3 dira dirb

$ echo dir{z..w} file{A..D}
dirz diry dirx dirw fileA fileB fileC fileD

$ echo dir{z..w} file{A..B} fileC
dirz diry dirx dirw fileA fileB fileC

glob / splitting disabilitato tramite virgolette doppie

$ echo "dir{z..w} file{A..B} fileC"
dir{z..w} file{A..B} fileC

$ echo "dir{z..w} file{A..B}"
dir{z..w} file{A..B}

Non sapevo che le gamme funzionassero anche in ordine inverso.
Joe
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.