I am trying to automate a process which involves running scripts on various machines via ssh. It is vital to capture both output and the return code (for the detection of errors).
Setting the exit code explicitly works as expected:
~$ ssh host exit 5 && echo OK || echo FAIL
FAIL
However, if there is a shell script signalling an unclean exit, ssh always returns 0 (script simulated by string execution):
~$ ssh host sh -c 'exit 5' && echo OK || echo FAIL
OK
Running the very same script on the host in an interactive shell works just fine:
~$ sh -c 'exit 5' && echo OK || echo FAIL
FAIL
I am confused as to why this happens. How can I tell ssh to propagate bash's return code? I may not change the remote scripts.
I am using public key authentication, the private key is unlocked – there is no need for user interaction. All systems are Ubuntu 18.04. Application versions are:
OpenSSH_7.6p1 Ubuntu-4ubuntu0.1, OpenSSL 1.0.2n 7 Dec 2017
GNU bash, Version 4.4.19(1)-release (x86_64-pc-linux-gnu)
Note: This question is different from these seemingly similar questions:
- bash shell - ssh remote script capture output and exit code?
- https://stackoverflow.com/questions/15390978/shell-script-ssh-command-exit-status
- https://stackoverflow.com/questions/36726995/exit-code-from-ssh-command
- https://superuser.com/questions/652729/command-executed-via-ssh-does-not-return-proper-return-code
sh -c 'sleep 0.1; exit 5'
?/bin/sh
actually points to/bin/dash
. Nevertheless the behaviour does not change if I use absolute paths (/bin/bash
and/bin/sh
instead ofsh
). I hope there is no further auto-redirect going on.ssh host sh -c ':; exit 5'
yields the expected return code. This does not help me as in the real world script, there is a lot more going on. I want to examine what forks where and then improve the examples in my question.