6

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

    4 Answers 4

    10

    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 
    8
    • OK, but now I don't have the stdout of the ls, and I need that.CommentedJan 28, 2017 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 stdoutCommentedJan 28, 2017 at 21:46
    • OK, how do I differentiate then?CommentedJan 28, 2017 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.CommentedJan 28, 2017 at 21:50
    • $? will also be non-zero if the ls fails.
      – Kusalananda
      CommentedJan 28, 2017 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
    • ssh or command (might be better to call it "remote shell code") may fail without reporting an error. The 2> ssh.err redirection could also fail. Or there may be warnings or informational messages on stderr that are not necessarily to be taken as errors. May be better as if ! output=$(ssh... 2> err) || [ -s err ]; then... or handle the failing command and presence of messages on stderr differently.CommentedFeb 17 at 16:32
    0

    As I remember some variant must work. Try this:

    cmd 2>>>$errmsg 

    triple redirect possibly... It was many years ago... in variable errmsg must be output error message. Maybe I am wrong. In this case this variant get message 100% guarantee:

    errmsg=`cmd 2>/dev/null` 

    This variant suppress error message while need it to out or may be not need. But usual output it catch also. So you may distinct those two cases by $? value and correct your script.

      0

      In Mac, accepted answer was not working. I tried from the reference link attached that worked for me. VAR=$((your-command-including-redirect) 2>&1)

      updating here for someone like me in the future.

      Referred from stackoverflow

      1
      • How would you know whether there’s an error message or your expected data in $VAR? Note that the user in the question want to some sort of indication when they can trust that they have the correct data in the variable.
        – Kusalananda
        CommentedFeb 17 at 15:42

      You must log in to answer this question.

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.