GNU/Linux >> Znalost Linux >  >> Linux

eval příkaz v Bash a jeho typické použití

eval vezme řetězec jako svůj argument a vyhodnotí jej, jako byste tento řetězec zadali na příkazovém řádku. (Pokud předáte několik argumentů, jsou nejprve spojeny mezerami mezi nimi.)

${$n} je syntaktická chyba v bash. Uvnitř složených závorek můžete mít pouze název proměnné s nějakou možnou předponou a příponou, ale nemůžete mít libovolnou bash syntaxi a zejména nemůžete používat expanzi proměnné. Existuje způsob, jak říci „hodnotu proměnné, jejíž jméno je v této proměnné“, ačkoli:

echo ${!n}
one

$(…) spustí příkaz zadaný v závorkách v dílčím prostředí (tj. v samostatném procesu, který zdědí všechna nastavení, jako jsou hodnoty proměnných, z aktuálního prostředí) a shromáždí jeho výstup. Takže echo $($n) běží $n jako příkaz shellu a zobrazí jeho výstup. Od $n se vyhodnotí jako 1 , $($n) pokusí se spustit příkaz 1 , který neexistuje.

eval echo \${$n} spustí parametry předané do eval . Po rozšíření jsou parametry echo a ${1} . Takže eval echo \${$n} spustí příkaz echo ${1} .

Všimněte si, že většinu času musíte kolem substitucí proměnných a substitucí příkazů používat dvojité uvozovky (tj. kdykoli se objeví $ ):"$foo", "$(foo)" . Náhrady proměnných a příkazů vždy umístěte do dvojitých uvozovek , pokud nevíte, že je musíte nechat vypnuté. Bez dvojitých uvozovek shell provede dělení pole (tj. rozdělí hodnotu proměnné nebo výstup z příkazu na samostatná slova) a poté každé slovo považuje za vzor zástupných znaků. Například:

$ 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 nepoužívá se příliš často. V některých shellech je nejběžnější použití k získání hodnoty proměnné, jejíž jméno není známo až do běhu. V bash to není nutné díky ${!VAR} syntax. eval je stále užitečné, když potřebujete vytvořit delší příkaz obsahující operátory, vyhrazená slova atd.


Jednoduše si eval představte jako „zhodnocení vašeho výrazu ještě jednou před provedením“

eval echo \${$n} se změní na echo $1 po prvním kole hodnocení. Tři změny na upozornění:

  • \$ se stal $ (Je potřeba zpětné lomítko, jinak se pokusí vyhodnotit ${$n} , což znamená proměnnou s názvem {$n} , což není povoleno)
  • $n byl vyhodnocen na 1
  • eval zmizel

Ve druhém kole je to v podstatě echo $1 které lze přímo provést.

Takže eval <some command> nejprve vyhodnotí <some command> (vyhodnocením zde myslím náhradní proměnné, nahraďte uvozené znaky správnými atd.) a poté spusťte výsledný výraz znovu.

eval se používá, když chcete dynamicky vytvářet proměnné nebo číst výstupy z programů speciálně navržených pro takovéto čtení. Příklady viz http://mywiki.wooledge.org/BashFAQ/048. Odkaz také obsahuje některé typické způsoby, jak eval se používá a rizika s ním spojená.


Podle mých zkušeností je "typické" použití eval pro spouštění příkazů, které generují příkazy shellu pro nastavení proměnných prostředí.

Možná máte systém, který používá kolekci proměnných prostředí, a máte skript nebo program, který určuje, které z nich by měly být nastaveny, a jejich hodnoty. Kdykoli spustíte skript nebo program, běží v rozvětveném procesu, takže vše, co dělá přímo s proměnnými prostředí, je při ukončení ztraceno. Ale tento skript nebo program může odeslat exportní příkazy do stdout.

Bez eval byste museli přesměrovat stdout do dočasného souboru, vytvořit zdroj dočasného souboru a poté jej odstranit. Pomocí eval můžete:

eval "$(script-or-program)"

Všimněte si, že uvozovky jsou důležité. Vezměte si tento (vymyšlený) příklad:

# 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. Rozdíl mezi ‚A‘ na příkazovém řádku (bash)??

  2. Příkaz „eval“ v Bash?

  3. příkaz pro export bash

  1. Proč by se měl v Bash vyhnout eval a co bych měl místo toho použít?

  2. Bash - příkaz Datum a mezera

  3. Jaký je rozdíl mezi &> a >&v bash?

  1. Dvě skvělá použití pro příkaz cp:Bash zkratky

  2. příkaz bash alias s jednoduchými i dvojitými uvozovkami

  3. Spusťte příkaz bash na jenkins pipeline