powłoka bash - ssh zdalny skrypt przechwytuje kod wyjściowy i kod zakończenia?

23

Chcę użyć powłoki do wywołania skryptu na zdalnym serwerze. Chciałbym uchwycić dane wyjściowe tego skryptu (jego komunikaty rejestrowania) i kod wyjścia, który zwraca.

Jeśli to zrobię:

ssh user@server /usr/local/scripts/test_ping.sh
echo "$?"

Otrzymuję kod wyjścia, ale nie mogę przechwycić wiadomości zdalnego logowania.

Jeśli to zrobię:

local RESULTS=$(ssh user@server /usr/local/scripts/test_ping.sh)
echo "$?" 
LOG "${RESULTS}";

Rejestruję dane wyjściowe za pomocą funkcji LOG, ale nie mogę uzyskać poprawnego kodu wyjścia, zakładam, że otrzymany kod jest kodem z przypisania zmiennej.

Chciałbym nadal używać mojej funkcji LOG do przechwytywania wszystkich danych wyjściowych podczas formatowania i wysyłania rzeczy do pliku, syslog i ekranu.

Jak przechwycić wyniki w zmiennej ORAZ uzyskać poprawny kod wyjścia ze zdalnego skryptu?

mconlin
źródło
tylko dane wyjściowe: superuser.com/questions/130443/… | unix.stackexchange.com/questions/1630/redirect-stdout-over-ssh
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Odpowiedzi:

37

Powodem, dla którego nie otrzymujesz poprawnego kodu błędu, jest to, że localfaktycznie jest to ostatnia wykonywana czynność. Przed uruchomieniem polecenia musisz zadeklarować zmienną jako lokalną.

local RESULTS
RESULTS=$(ssh user@server /usr/local/scripts/test_ping.sh)
echo $?

Możesz zobaczyć problem tutaj:

$ bar() { foo=$(ls asdkjasd 2>&1); echo $?; }; bar
2
$ bar() { local foo=$(ls asdkjasd 2>&1); echo $?; }; bar
0
$ bar() { local foo; foo=$(ls asdkjasd 2>&1); echo $?; }; bar
2
Jordan
źródło
8

Problemem wydaje się „lokalny”. To działa dla mnie:

local RESULTS
RESULTS=$(ssh user@server /usr/local/scripts/test_ping.sh)
echo $?
Hauke ​​Laging
źródło
też miałeś rację, ale jodanm był szybszy!
mconlin
Tak, 26 sekund.
Hauke ​​Laging
5
Nie jest to lekcja angielskiego, ale niepoprawne jest mówienie „więcej szybciej”.
mtahmed
5
Wiem, że to był żart. Chyba zły. W Internecie nikt nie wie, że jesteś psem.
mconlin,
także odpowiedź jordanma wyjaśnia, DLACZEGO to był problem :)
Doktor J
3

W rzeczywistości żadna z powyższych odpowiedzi nie przechwytuje kodu błędu i komunikatu ssh, co można wykonać w następujący sposób (zignoruj ​​moje funkcje niestandardowe):

# move the deployment package from the tmp dir
msg=$(ssh -i "$(eval echo $identity_file)" -o ConnectTimeout=5 "$ssh_user"'@'"$ssh_server" \
sudo -iu "$etl_user" bash "$tgt_deployment_dir"'/src/bash/'"$run_unit/$run_unit"'.sh' \
    -a create-relative-package 2>&1)

# fail on any non-success
export exit_code=$?
export err_msg="network error: ""$msg"
test $exit_code -ne 0 && doExit $exit_code $err_msg
Yordan Georgiev
źródło