GNU/Linux >> Linux Esercitazione >  >> Linux

comando eval in Bash e i suoi usi tipici

eval accetta una stringa come argomento e la valuta come se avessi digitato quella stringa su una riga di comando. (Se passi diversi argomenti, vengono prima uniti con spazi tra loro.)

${$n} è un errore di sintassi in bash. All'interno delle parentesi graffe, puoi avere solo un nome di variabile, con alcuni possibili prefissi e suffissi, ma non puoi avere una sintassi bash arbitraria e in particolare non puoi usare l'espansione delle variabili. C'è un modo per dire "il valore della variabile il cui nome è in questa variabile", però:

echo ${!n}
one

$(…) esegue il comando specificato all'interno delle parentesi in una subshell (ovvero in un processo separato che eredita tutte le impostazioni come i valori delle variabili dalla shell corrente) e ne raccoglie l'output. Quindi echo $($n) esegue $n come comando di shell e ne visualizza l'output. Dal $n restituisce 1 , $($n) tenta di eseguire il comando 1 , che non esiste.

eval echo \${$n} esegue i parametri passati a eval . Dopo l'espansione, i parametri sono echo e ${1} . Quindi eval echo \${$n} esegue il comando echo ${1} .

Nota che la maggior parte delle volte devi usare le virgolette doppie per sostituire le variabili e sostituire i comandi (ad esempio ogni volta che c'è un $ ):"$foo", "$(foo)" . Metti sempre le doppie virgolette attorno alle sostituzioni di variabili e comandi , a meno che tu non sappia che devi lasciarli fuori. Senza le virgolette doppie, la shell esegue la divisione del campo (ovvero divide il valore della variabile o l'output del comando in parole separate) e quindi tratta ogni parola come un modello di carattere jolly. Ad esempio:

$ ls
file1 file2 otherfile
$ set -- 'f* *'
$ echo "$1"
f* *
$ echo $1
file1 file2 file1 file2 otherfile
$ n=1
$ eval echo \${$n}
file1 file2 file1 file2 otherfile
$eval echo \"\${$n}\"
f* *
$ echo "${!n}"
f* *

eval non è usato molto spesso. In alcune shell, l'uso più comune è ottenere il valore di una variabile il cui nome non è noto fino al runtime. In bash, questo non è necessario grazie al ${!VAR} sintassi. eval è comunque utile quando devi costruire un comando più lungo contenente operatori, parole riservate, ecc.


Pensa semplicemente a eval come "valutare la tua espressione un'altra volta prima dell'esecuzione"

eval echo \${$n} diventa echo $1 dopo il primo giro di valutazione. Tre modifiche da notare:

  • Il \$ è diventato $ (La barra rovesciata è necessaria, altrimenti tenta di valutare ${$n} , che significa una variabile denominata {$n} , che non è consentito)
  • $n è stato valutato a 1
  • Il eval scomparso

Nel secondo round, è fondamentalmente echo $1 che può essere eseguito direttamente.

Quindi eval <some command> valuterà prima <some command> (per valutare qui intendo sostituire le variabili, sostituire i caratteri sfuggiti con quelli corretti ecc.), quindi eseguire nuovamente l'espressione risultante.

eval viene utilizzato quando si desidera creare dinamicamente variabili o leggere output da programmi specificamente progettati per essere letti in questo modo. Vedere http://mywiki.wooledge.org/BashFAQ/048 per esempi. Il collegamento contiene anche alcuni modi tipici in cui eval viene utilizzato e i rischi ad esso associati.


Nella mia esperienza, un uso "tipico" di eval è per l'esecuzione di comandi che generano comandi shell per impostare variabili d'ambiente.

Forse hai un sistema che utilizza una raccolta di variabili d'ambiente e hai uno script o un programma che determina quali dovrebbero essere impostati e i loro valori. Ogni volta che esegui uno script o un programma, viene eseguito in un processo biforcuto, quindi tutto ciò che fa direttamente alle variabili di ambiente viene perso quando esce. Ma quello script o programma può inviare i comandi di esportazione a stdout.

Senza eval, dovresti reindirizzare stdout a un file temporaneo, generare il file temporaneo e quindi eliminarlo. Con eval, puoi semplicemente:

eval "$(script-or-program)"

Nota che le virgolette sono importanti. Prendi questo esempio (artificioso):

# activate.sh
echo 'I got activated!'

# test.py
print("export foo=bar/baz/womp")
print(". activate.sh")

$ eval $(python test.py)
bash: export: `.': not a valid identifier
bash: export: `activate.sh': not a valid identifier
$ eval "$(python test.py)"
I got activated!

Linux
  1. Due ottimi usi per il comando cp:scorciatoie Bash

  2. Differenza tra "e" sulla riga di comando (bash)??

  3. Il comando "eval" in Bash?

  4. comando di esportazione bash

  5. Bash - Comando data e spazio

Comando sorgente Bash

Comando della cronologia in Linux (Cronologia di Bash)

Comando di uscita Bash e codici di uscita

Comando Bash printf

Come leggere l'output e gli usi dei comandi principali di Linux

Script Bash(II)