Co je substituce příkazů v shellu? [duplicate]

Tato otázka již má odpovědi zde :

Komentáře

  • Dobře, každý si musí odpočinout a přestat se navzájem obviňovat z trollování. Pokud se vám ' nelíbí otázka, hlasujte proti ní nebo ji ignorujte a odejděte . Pokud máte pocit, že jste ' napadeni v komentářích, nezapojujte se, ale označte a odcházejte .
  • Také související: Jaký je ' rozdíl mezi $ (stuff) a `stuff`?
  • Zobrazení výstup příkazu pomocí substituce příkazu a echo je špatným příkladem substituce příkazu, protože 1) výstup by byl stejně zobrazen, 2) printf je bezpečnější použít pro variabilní data. Příklad by mohl být také napsán date | sed 's/^/Today is /'
  • @Kusalananda. Vidím váš názor na okamžité vytištění (pomocí printf ) je k ničemu. Trochu jsem změnil frázování z okamžitě na sometime later, je to přitažlivější?
  • Příkladem může být thedate=$(date), následuje printf 'The date is %s\n' "$thedate".

Odpověď

" Substituce příkazů " je název funkce jazyka shellu, který vám umožňuje provést příkaz a nechat výstup tohoto příkazu nahradit ( substitute) text příkazu.

Neexistuje žádná jiná funkce jazyka shellu, která by vám to umožňovala.

Substituce příkazu, tj. celá $(...) výraz, je nahrazen jeho výstupem, který je primárním použitím substitucí příkazů.

Příkaz, který se provádí substitucí příkazu, se provádí v subshell, což znamená, že má své vlastní prostředí, které nebude mít vliv na prostředí nadřazeného prostředí.

Ne všechna provedení subshell jsou substitutami příkazů fuj (viz další příklady na konci).

Příklad ukazující, že substituce příkazu je provedena v subshellu:

$ s=123 $ echo "hello $( s=world; echo "$s" )" hello world $ echo "$s" 123 

Zde je proměnná s je nastavena na řetězec 123. Na dalším řádku je echo vyvolán na řetězci obsahujícím výsledek nahrazení příkazu. Substituce příkazu nastaví s na řetězec world a ozve se tento řetězec. Řetězec world je výstup příkazu v substituci příkazu , a tedy pokud byl spuštěn pod set -x, uvidíme, že druhý řádek výše by byl rozšířen na echo "hello world", který na terminálu vytvoří hello world:

$ set -x $ echo "hello $( s=world; echo "$s" )" ++ s=world ++ echo world + echo "hello world" hello world 

(bash přidává další úroveň výzev + na každou úroveň Substituce nahrazení příkazu ve výstupu trasování, ostatní skořápky to nemusí dělat.

Nakonec ukážeme, že příkaz uvnitř substituce příkazu byl spuštěn ve vlastní podsestavě, protože neovlivnil hodnotu s ve volajícím shellu (hodnota s je stále 123, ne world).

Existují i jiné situace, kdy jsou příkazy prováděny v dílčích skořápkách, například v

echo "hello" | read message 

V bash, pokud nenastavíte možnost lastpipe (pouze v neinteraktivních případech), provede se read v subshelmu, což znamená že $message se v nadřazeném prostředí nezmění, tj. echo "$message" poté, co výše uvedený příkaz ozve prázdný řetězec (nebo jakoukoli hodnotu $message byl předtím).

Substituce procesu v bash se také provádí v subshellu:

cat < <( echo "hello world" ) 

Toto je také odlišné od nahrazení příkazu.

Komentáře

  • Pro verzi bash 4.2 up, pokud shopt lastpipe je nastaven, řízení úloh není aktivní a kanál není na pozadí, poslední příkaz se nespustí v subshellu.
  • Říkáte: „Neexistuje žádná jiná funkce jazyka shellu, která by vám to umožňovala.“ S rizikem štěpení vlasů můžete cmd₁ > myfile / read -r var < myfile / cmd₂ "$var" . V případě potřeby to můžete rozšířit tak, aby zpracovávalo víceřádkové údaje.
  • @ G-Man Ano, můžete také do souboru napsat nový skript prostředí a provést jej.Neexistuje žádná jiná funkce, která by poskytovala způsob nahrazení části textu výstupem příkazu.

Odpovědět

a=$(command) 

uloží do proměnné výslednou hodnotu command.

Už to opravdu není.

Jako vedlejší poznámku se domnívám:

a=`command` 

byl zastaralý a má stejný význam jako výše.

Komentáře

  • výsledek zde je standardní výstup příkazu zbaveného všech jeho koncových nových řádků znaků (a některé rozdíly mezi skořápkami, pokud je výstup netextový). Všimněte si, že `...` je Bourneova syntaxe csh, zatímco $(...) je syntaxe Korn / POSIX (s `...` stále podporováno z důvodu zpětné kompatibility)
  • @St é phaneChazelas Děkujeme za cenné informace a neváhejte upravit odpověď tak, aby je obsahovala.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *