0

I’m working on a bash script that will ssh to a remote machine and execute a series of commands there. I’m new to ssh. I’m trying several ways on how to do this the cleanest way possible. I saw on this website that one option is to pass a heredoc (“here document”) to the ssh command. I also want to use the bash option set –x for debugging.

I’m trying several things to see what my options are. I do not understand why the following behavior happens. If I run:

ssh remote_machine bash -x <<- REMOTE
    echo pear
    echo apple
REMOTE

the following is shown:

pear
apple
+ echo pear
+ echo apple

As you can see, the output is not in order. But if I do locally:

bash -x <<- REMOTE
    echo pear
    echo apple
REMOTE

the following is shown:

+ echo pear
pear
+ echo apple
apple

as it should be.

I tried to find the answer online but couldn’t find anything. Any ideas?


E D I T 1: According to @user1934428,

The output of echo goes to stdout, and the output of -x goes to stderr, and ssh has to catch somehow the two streams and can't know how to sync them.

I searched online if it's possible to "merge" stderr and stdout for multiple commands. This is possible, with line exec 2>&1. This redirects the stderr to stdout for succeeding commands. See more here: sh command: exec 2>&1

So now I can do:

ssh remote_machine bash <<- REMOTE
    exec 2>&1
    set -x
    echo pear
    echo apple
    echo peach
    echo plum
REMOTE

which yields:

+ echo pear
pear
+ echo apple
apple
+ echo peach
peach
+ echo plum
plum

I'll need some time to consider the implications of this and to decide if I'm OK with this behavior.

  • 1
    The output of `echo` goes to stdout, and the output of `-x` goes to stderr, and `ssh` has to catch somehow the two streams and can't know how to sync them. I would however have expected the opposite order (i.e. stderr output first), because stderr is usually unbuffered. What happens if you, instead of using `-x`, explicitly output something to stderr? – user1934428 Dec 15 '21 at 13:04
  • Thank you for your reply @user1934428. If I run: `ssh remote_machine bash <<- REMOTE echo pear > /dev/stderr; echo plum; echo peach; echo apple > /dev/stderr; REMOTE` I get `plum peach pear apple` every time. So it looks like it first outputs from stdout and then from stderr. – We_dig_dig_dig_dig_dig_dig_dig Dec 15 '21 at 14:43
  • Trying this a few times, it doesn't seem like the order is fixed with ssh. The reason that the order is fixed when executing the command locally is that both stdout and stderr are connected to the same tty. I've mucked around with `ssh -tt`, hoping to create the same situation, but that'll make bash think it's in interactive mode. I found `ssh $host bash -x '2>&1'` to work. The command that you pass to ssh will actually be executed by the login(?) shell, and you can use that to make stdout and stderr be the same. – Caesar Dec 15 '21 at 14:57
  • 1
    @Caesar : It's not documented, but seems to work: When I invoke `bash` with the option `+i`, it believes that it is not interactive. You can verify it with `bash +i -c 'echo $-'`. – user1934428 Dec 16 '21 at 07:46

0 Answers0