5

I have the following line in my bash file:

LIST=$(ssh 192.168.0.22 'ls -1 /web');

The problem I am having is that it is a part of automated script and I often get this on the stdout and not the data I need:

ssh_exchange_identification: Connection closed by remote host

I realize that LIST only gets the stdout of the ls. So I am looking for a command that would get more of the info from the commands. In particular:

  • stdout for ls - I have that right now
  • stderr for ls - not really interested, I don't expect a problem there
  • stdout for ssh - Not interested, I don't even know what it would output
  • stderr for ssh - THIS IS WHAT I AM LOOKING FOR to check whether it ssh correctly. This being empty should mean that I have the data in $LIST I expect
5

From ssh man page on Ubuntu 16.04 (LTS):

EXIT STATUS
     ssh exits with the exit status of the remote command or with 255 if an error occurred.

Knowing that, we can check exit status of ssh command. If exit status was 225, we know that it's an ssh error, and if it's any other non-zero value - that's ls error.

#!/bin/bash

TEST=$(ssh $USER@localhost 'ls /proc' 2>&1)

if [ $? -eq 0 ];
then
    printf "%s\n" "SSH command successful"
elif [ $? -eq 225   ]
    printf "%s\n%s" "SSH failed with following error:" "$TEST"
else 
    printf "%s\n%s" "ls command failed" "$TEST"
fi
  • OK, but now I don't have the stdout of the ls, and I need that. – Patrick Kusebauch Jan 28 '17 at 21:44
  • @PatrickKusebauch Does your ssh connection produce error simultaneously with ls producing output ? If not, what's going to be stored in the variable is either ssh's stderr or ls's stdout – Sergiy Kolodyazhnyy Jan 28 '17 at 21:46
  • OK, how do I differentiate then? – Patrick Kusebauch Jan 28 '17 at 21:48
  • @PatrickKusebauch You could check $? variable. If there was an error, it would be equal to non-zero value. I'll add example in a moment. – Sergiy Kolodyazhnyy Jan 28 '17 at 21:50
  • $? will also be non-zero if the ls fails. – Kusalananda Jan 28 '17 at 22:03
3

Redirect ssh's standard error to a file within the command substitution and then test to see whether the file is empty or not:

output="$( ssh server 'command' 2>ssh.err )"

if [[ -s ssh.err ]]; then
    echo 'SSH error:' >&2
    cat ssh.err >&2
fi

rm -f ssh.err

which displays SSH error: followed by the captured error output from ssh.

  • 1
    IIRC the double quotes around process substitution aren't necessary when assigning to a variable. They're only necessary to avoid word splitting when process substitution is passed as argument to another command. – Sergiy Kolodyazhnyy Jan 28 '17 at 21:44
  • @Serg According to Stéphane Chazelas (whom I trust quite a bit on these issues), one should always double quote variable expansions, command substitutions, and arithmetic expansions (unless there is a particular reason not to, I assume, and there seldom is). unix.stackexchange.com/a/171347/116858 – Kusalananda Jan 28 '17 at 21:52
  • @Serg You might be correct when it comes to assignments, but I don't want too many rules to keep track of, so I double quote anyway. It doesn't hurt. – Kusalananda Jan 28 '17 at 21:53
  • Ad 2nd solution: I don't want the error to be displayed directly. I want to have control when and how I display the error. – Patrick Kusebauch Jan 28 '17 at 22:07
  • @PatrickKusebauch So, my first alternative does exactly that. Just cat the ssh.err file whenever you want to, if its size is non-zero (tested with the -s test as in my code). – Kusalananda Jan 28 '17 at 22:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.