it-swarm-eu.dev

Jak mohu přiřadit výstup příkazu proměnné Shell?

Chci přiřadit výsledek výrazu k proměnné a zřetězit ji řetězcem, pak ji opakovat. Tady je to, co mám:

#!/bin/bash
cd ~/Desktop;
thefile= ls -t -U | grep -m 1 "Screen Shot";
echo "Most recent screenshot is: "$thefile;

Výstupy:

Screen Shot 2011-07-03 at 1.55.43 PM.png
Most recent screenshot is: 

Vypadá to, že to není přiřazeno k $thefile a tiskne se, jakmile je spuštěn.

82
Nathan G.

Shell přiřazení je jediné slovo, bez mezery za znaménkem rovnosti. To, co jste napsali, přiřadí prázdnou hodnotu thefile; dále, protože přiřazení je seskupeno s příkazem, vytváří thefile proměnnou prostředí a přiřazení je místní pro tento konkrétní příkaz, tj. pouze přiřazené hodnotě vidí pouze volání ls.

Chcete zachytit výstup příkazu, takže musíte použít substituce příkaz :

thefile=$(ls -t -U | grep -m 1 "Screen Shot")

(Některá literatura ukazuje alternativní syntaxi thefile=`ls …`; Syntaxe backquote je ekvivalentní syntaxi dolarových závorek s výjimkou toho, že citace uvnitř backquotů jsou někdy podivné, takže stačí použít $(…).)

Další poznámky k vašemu skriptu:

  • Kombinace -t (Třídění podle času) s -U (Netřídit) nedává smysl; stačí použít -t.
  • Spíše než použití grep k porovnávání snímků obrazovky, je jasnější předat zástupný znak ls a pomocí head zachytit první soubor:

    thefile=$(ls -t *"Screen Shot"* | head -n 1)
    
  • Obecně je to špatný nápad analyzovat výstup ls . To může selhat docela špatně, pokud máte názvy souborů s netisknutelnými znaky. Třídění souborů podle data je však obtížné bez ls, takže je to přijatelné řešení, pokud víte, že v názvech souborů nebudete mít netisknutelné znaky nebo zpětná lomítka.

  • Vždy používejte dvojité uvozovky kolem proměnných substitucí , tj. Zde napište

    echo "Most recent screenshot is: $thefile"
    

    Bez uvozovek je hodnota proměnné znovu rozšířena, což způsobí potíže, pokud obsahuje mezeru nebo jiné speciální znaky.

  • Na konci řádku nepotřebujete středníky. Jsou nadbytečné, ale neškodné.
  • Ve skriptu Shell je často dobré zahrnout set -e . Toto řekne prostředí, aby ukončilo případný příkaz, který selže (vrácením nenulového stavu).

Pokud máte GNU najít (zejména pokud používáte nezařazený Linux nebo Cygwin), existuje další přístup k nalezení nejnovějšího souboru: nechte find seznam souborů a jejich data a pomocí sort a tail extrahujte nejmladší soubor.

thefile=$(find -maxdepth 1 -type f -name "*Screen Shot*" -printf "%[email protected] %p" |
          sort -k 1n | tail -n 1)

Pokud jste ochotni napsat tento skript v zsh místo bash, existuje mnohem jednodušší způsob, jak zachytit nejnovější soubor, protože zsh má glob kvalifikátory , které umožňují zástupné zápasy nejen na jména, ale také na soubor metadata. Část (om[1]) Za vzorem je kvalifikace glob; om třídí zápasy podle rostoucího věku (tj. podle času modifikace, nejnovějšího prvního) a [1] extrahuje pouze první zápas. Celá shoda musí být uvedena v závorkách, protože je to technicky pole, protože globbing vrací seznam souborů, i když [1] Znamená, že v tomto konkrétním případě seznam obsahuje (nejvýše) jeden soubor.

#!/bin/zsh
set -e
cd ~/Desktop
thefile=(*"Screen Shot"*(om[1]))
echo "Most recent screenshot is: $thefile"

Pokud to chcete udělat pomocí víceřádkových/více příkazů/s, můžete to udělat:

output=$( bash <<EOF
#multiline/multiple command/s
EOF
)

Nebo:

output=$(
#multiline/multiple command/s
)

Příklad:

#!/bin/bash
output="$( bash <<EOF
echo first
echo second
echo third
EOF
)"
echo "$output"

Výstup:

first
second
third
4
Jahid