Zápisník

// Čtení výstupu vzdáleného příkazu s Dropbear ssh klientem

Dneska jsem při programování jednoho skriptu narazil na drobný problém s Dropbear SSH klientem (dbclient) na mém domácím OpenWRT routeru. Rád bych zde podotkl, že nemám nejnovější verzi, ale verzi dostupnou v mé OpenWRT instalaci. Přesněji, je to Dropbear v0.53.1. Ale spousta distribucí nemá nejnovější verze, takže budu doufat, že to někomu přijde užitečné.

Mám shell skript, který používá ssh klienta na čtení informací z jiného serveru. Představte si následující kus kódu:

result=`ssh -i key_file user@server remote_command` && {
  echo "Obtained information is $result"
}

Kód způsobí připojení na vzdálený počítač a spuštění příkazu remote_command, který vypíše nějaký text. Tento výstup se přiřadí do proměnné $result. Pokud vzdálený příkaz skončí úspěšně (vrátí návratový kód 0), vypíše se zpráva se získanou hodnotou.

Z nějakého důvodu tento kód nefungoval v rámci skriptu spuštěného cronem. Hodně jsem googlil a našel popis problému v mailinglistu včetně jakéhosi řešení. Důvodem problému je to, že skript spuštěný cronem nemá k dispozici standardní vstup. Díky tomu se dbclient neobtěžuje vypisovat výsledek volání příkazu na výstup, takže proměnné $result je nastavena prázdná hodnota a není vrácen chybový kód.

Toto chování může být simulováno následovně:

ssh -i key_file user@server echo "foo" </dev/null

Nic se nevypíše. OpenSSH klienta (implementace SSH na běžných linuxových distribucích) toto neovlivní a stále funguje tak, jak má.

Nejrychlejší řešení je poskytnout ssh klientovi nějaký standardní vstup, zde postačilo přesměrovaní z /dev/zero. Následující tedy již funguje:

result=`ssh -i key_file user@server remote_command </dev/zero` && {
  echo "Obtained information is $result"
}

Nyní celý skript běží správně, jak samostatně spuštěný, tak i z cronu.