Bash: usare una variabile per costruire un comando (con wildcards)

Poniamo che in uno script vogliamo eseguire un comando, i cui parametri sono all'interno di una variabile (o, più in generale, parte o tutta la linea di comando è presente in una variabile). Normalmente eseguiremo una cosa del genere:

PARAMS="-par1 -par2"
command $PARAMS

Fin qui nessun problema. Gli scogli arrivano se dentro $PARAMS sono presenti delle wildcards, ad esempio:

PARAMS="-par1 --exclude={/dir1/*,/dir2/*}"
command $PARAMS

In questo caso l'esecuzione del comando non funziona o, meglio, non funziona allo stesso modo di aver eseguito direttamente:

command -par1 --exclude={/dir1/*,/dir2/*}

Infatti l'espansione delle wildcards avviene prima dell'esecuzione del comando, durante la generazione della commandline, e questo fa si che l'effettivo comando eseguito sia:

command -par1 --exclude={/dir1/a /dir1/b /dir1/c,/dir2/a /dir2/b /dir2/...}

Spesso questo potrebbe non essere un problema reale (semplicemente viene fatta l'espansione prima del previsto). Ma a volte invece potrebbe essere un errore: ad esempio nel caso sopra la separazione con "," viene violata, senza contare che se con l'espansione la command line diventa troppo lunga il sistema potrebbe bloccare tutto.

Altro caso in cui l'espansione preventiva può creare dei problemi è quando nella command line sono presenti degli escaping (allo scopo proprio di evitare l'espansione e di passare il carattere "*" al comando).

Come fare in questi casi?

Semplice, usare il comando "eval", che deve essere posto a inizio riga:

PARAMS="-par1 --exclude={/dir1/*,/dir2/*}"
eval command $PARAMS

Commenti

  1. Andrea ·

    Ho provato a fare uno script del tipo

    eval ls -l $1 ; eval du $2 Poi l'ho lanciarlo con ./script file* pippo* in una directory dove ho file1,file2, ..fileN e pippo1, pippo2, .., pippoN, tutti vuoti.

    Mi esce
    -rw-r--r-- 1 celli celli 0 2013-03-01 15:59 file1 0 file2

    Dove sbaglio? Andrea

  2. admin ·

    Ciao andrea,

    l'articolo parla della possibilità di inserire le wildcards "*" all'interno di variabili in uno script, quindi è una situazione diversa da quella che descrivi.

    Quando usi le wildcards via riga di comando (passandole come semplici parametri, come nel tuo caso) queste vengono espanse subito. In pratica al tuo "./script" vengono passati direttamente i nomi di file che risultano dall'espressione "file*" e "pippo*", e non le espressioni. In questo modo lo script non ha modo di sapere che hai scritto "file*", lui riceve direttamente "file1 file2 file3 file4...".

    Credo che per passare le wildcard dall'esterno devi lavorare con gli apici in riga di comando. Qualcosa del tipo

    [./script "file*" "pippo*"]

    o qualcosa di simile... fai qualche prova.

Lascia un commento

Stai rispondendo a Andrea.

Il tuo indirizzo email non sarà pubblicato. I commenti vengono pubblicati dopo la moderazione.