Portál AbcLinuxu, 16. července 2025 11:24


Dotaz: Output command to variable

10.11.2020 17:05 Lukáš
Output command to variable
Přečteno: 454×
Odpovědět | Admin
Ahoj, nemohu přijít na lehký programátorský oříšek :-)

Prosím Vás, jak docílím uložení výstupu příkazu do proměnné v bashi? Standartně je syntaxe:
c=$(pwr)
echo "Output ${c}"
To tak FUNGUJE!

--------------------------------------------------------------------------
Ale potřebuji výstup z příkazu "nc"
c=$(nc -v -z 192.168.1.222 80)
echo "Output ${c}"
Toto NEFUNGUJE

Ve výstupu mám:
Connection to 192.168.1.222 80 port [tcp/http] succeeded!
Output
Proměnná "c" je prázdná. Jak prosím uložím příkaz "nc" do proměnné?

Všem moc děkuji za pomoc Lukáš
Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

10.11.2020 17:32 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
Rozbalit Rozbalit vše Re: Output command to variable
Odpovědět | | Sbalit | Link | Blokovat | Admin
Pokud chcete stáhnout obsah dostupný přes http, je nc zbytečně nízkoúrovňové. Použijte třeba curl:

O=$(curl http://192.168.0.1/index.html)
-- OldFrog
10.11.2020 18:43 pavele
Rozbalit Rozbalit vše Re: Output command to variable
c=$(nc -v -z 127.0.0.1 80 1 2>&1)
10.11.2020 19:54 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
Rozbalit Rozbalit vše Re: Output command to variable
c=$(nc -v -z 127.0.0.1 80 1 2>&1)
Pořád mi přijde curl pro daný úkol snadnější, porovnej curl:
# curl www.root.cz

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://www.root.cz/">here</a>.</p>
<hr>
<address>Apache/2.4.25 (Debian) OpenSSL/1.0.2l Server at www.root.cz Port 80</address>
</body></html>
čili:
# curl https://www.root.cz

<!DOCTYPE html>
<!--
Zdá se, že se zajímáš o náš zdrojový kód...
Hledáme posilu do našeho týmu!
@erik.dvorak@iinfo.cz
--><html id="css" class="js-inactive design-html" lang="cs">
(...)
vs nc:
# nc -v -z www.root.cz 80
Connection to www.root.cz 80 port [tcp/http] succeeded!
-- OldFrog
11.11.2020 08:29 jiwopene | skóre: 31 | blog: Od každého trochu…
Rozbalit Rozbalit vše Re: Output command to variable
On chce otestovat to, jestli je port otevřený (nc -z), ne poslat HTTP požadavek.
.sig virus 3.2_cz: Prosím, okopírujte tento text do vaší patičky.
11.11.2020 14:36 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
Rozbalit Rozbalit vše Re: Output command to variable
Oops, máte pravdu.

Ale to bych pak testoval nějak takto:

nc -v -z 127.0.0.1 81 && echo OTEVRENY || echo ZAVRENY;
-- OldFrog
12.11.2020 09:18 jiwopene | skóre: 31 | blog: Od každého trochu…
Rozbalit Rozbalit vše Re: Output command to variable
A bez toho -v.
.sig virus 3.2_cz: Prosím, okopírujte tento text do vaší patičky.
10.11.2020 17:36 jiwopene | skóre: 31 | blog: Od každého trochu…
Rozbalit Rozbalit vše Re: Output command to variable
Odpovědět | | Sbalit | Link | Blokovat | Admin
Zápis nazev_promenne=="$(příkaz)" uloží do proměnné standardní výstup (stdout) příkazu. Každý program spuštěný ze shellu má ve výchozím stavu tyto výstupy: V shellu jste se pravděpodobně setkal s přesměrováním. Syntaxe je následující:
# standardní výstup jde do souboru
příkaz >soubor

# standardní vstup jde ze souboru
příkaz <soubor

# standardní výstup příkaz1 jde na standardní vstup příkaz2
příkaz1 | příkaz2
Můžete si všimnout toho, že všechny případy se týkají jen standardního vstupu a výstupu. Chybový výstup jde ve výchozím nastavení do terminálu. Pokud ho chcete přesměrovat do souboru, vypadá to takto:
# chybový výstup jde do souboru
příkaz 2>soubor
Ta dvojka znamená file descriptor číslo 2, tedy stderr. Podobně můžete nastavit i jiné FD než stdout a stderr, ale to v praxi většinou nepoužijete.

Můžete také přesměrovat stderr do stdout tím, že do cílového souboru napíšete &2 (FD číslo 2)2:
# chybový výstup (fd 2) se sloučí se standardním (fd 1), takže je veškerý výstup na standardním
příkaz 2>&1
To můžete pak vzít a přesměrovat do souboru nebo jiného příkazu:
# chybový výstup (fd 2) se sloučí se standardním (fd 1), standardní se pak směruje do souboru
příkaz 2>&1 >soubor

# chybový výstup příkazu 1 (fd 2) se sloučí se standardním příkazu 1 (fd 1), standardní se pak směruje do příkazu 2 (příkaz 2 už má ale opět oba výstupy)
příkaz1 2>&1 | příkaz2

Takže co tam má být?

nc tuto hlášku vypisuje na standardní chybový výstup, takže je chceme sloučit a to potom uložit do proměnné:
c="$(nc -vz 192.168.1.222 80 2>&1)"

Rada na závěr:

Pokud máte v shellu proměnnou, pište ji do uvozovek. Srovnejte tyto dva zápisy:
a=$(echo lorem ipsum)
b="$(echo lorem ipsum)"
Po vyhodnocení $(…) bash vidí toto:
a=lorem ipsum
b="lorem ipsum"
První řádek znamená „spusť příkaz „ipsum“ s proměnnou prostředí „a“ nastavenou na „lorem“.

Druhý řádek znamená „ulož do proměnné „b“ text „lorem ipsum“.

Toto je častý zdroj chyb v bashových programech.

[1] Trochu odlišně se bufferuje a některé emulátory terminálu ho mohou jinak zpracovávat – např. zobrazit jinou barvou. [2] S tímhle je možné dělat i poměrně nečitelné věci. Příkaz exec je možné použít ke směrování file deskriptorů samotného shellu.
.sig virus 3.2_cz: Prosím, okopírujte tento text do vaší patičky.
10.11.2020 17:41 jiwopene | skóre: 31 | blog: Od každého trochu…
Rozbalit Rozbalit vše Re: Output command to variable
Ještě jedna věc:

Příkaz má i svůj exit status (česky asi návratový kód), tedy číselný popis stavu po ukončení. Většina příkazů funguje tak, že ho nastaví na nenulovou hodnotu při chybě, jinak je 0. To umožňuje tvořit podmínky:
if příkaz1
then
        toto se provede pokud příkaz1 uspěl
fi

if příkaz2
then
        toto se provede pokud příkaz2 uspěl
else
        toto se provede pokud příkaz2 neuspěl
fi
.sig virus 3.2_cz: Prosím, okopírujte tento text do vaší patičky.
11.11.2020 09:00 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Output command to variable
Pokud máte v shellu proměnnou, pište ji do uvozovek. Srovnejte tyto dva zápisy:
a=$(echo lorem ipsum)
b="$(echo lorem ipsum)"
Po vyhodnocení $(…) bash vidí toto:
a=lorem ipsum
b="lorem ipsum"
První řádek znamená „spusť příkaz „ipsum“ s proměnnou prostředí „a“ nastavenou na „lorem“.

Druhý řádek znamená „ulož do proměnné „b“ text „lorem ipsum“.

Toto je častý zdroj chyb v bashových programech.

Obecně máte pravdu, ale zrovna u přiřazení je to trochu složitější, takže ten váš příklad nefunguje tak, jak tvrdíte:

mike@lion:~> var=$(echo lorem ipsum)
mike@lion:~> echo ">$var<"
>lorem ipsum<
10.11.2020 17:37 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: Output command to variable
Odpovědět | | Sbalit | Link | Blokovat | Admin

To hlášení píše nc na chybový výstup, nikoliv na standardní výstup. Proto se objevuje na terminálu a ne v proměnné.

c="$(netcat -v -z 2a02:xxxx:yyyy:2:defb:48ff:fe28:4f42 80 2>&1)"

Takhle^^^ mi to normálně funguje:

$ echo "$c"
Connection to 2a02:xxxx:yyyy:2:defb:48ff:fe28:4f42 80 port [tcp/http] succeeded!

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.