3

I need to get indication whatever the ssh command succeeded or not without it leaving the connected server.

I use this command:

ssh -q  user1@server1 "echo 2>&1" && echo SSH_OK || echo SSH_NOK

My problem with that command is that I don't stay in the connected server. I don't wish to add test after the ssh command, I wish to do it like how I do it so far - by one command.

Here is a sample of how it works now:

[nir@dhcppc4 ~]$ ssh -q  user1@server1 "echo 2>&1" && echo SSH_OK || echo SSH_NOK
SSH_NOK
[nir@dhcppc4 ~]$ hostname
dhcppc4
[nir@dhcppc4 ~]$ ssh -q  user1@server2 "echo 2>&1" && echo SSH_OK || echo SSH_NOK
SSH_OK
[nir@dhcppc4 ~]$ hostname
dhcppc4

And here is a sample of what I want:

[nir@dhcppc4 ~]$ ssh -q  user1@server1 "echo 2>&1" && echo SSH_OK || echo SSH_NOK
SSH_NOK
[nir@dhcppc4 ~]$ hostname
dhcppc4
[nir@dhcppc4 ~]$ ssh -q  user1@server2 "echo 2>&1" && echo SSH_OK || echo SSH_NOK
SSH_OK
[nir@server2 ~]$ hostname
server2
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
Nir
  • 1,335

6 Answers6

4

You need to output "SSH_OK" on the remote server and "SSH_NOK" on localhost:

ssh -t -q $host 'echo '"$host"'SSH_OK; exec $SHELL' || echo "$host: SSH_NOK"

But I would stick to John's suggestion of setting the prompt to indicate on what machine you are - and it is actually what you suggested in your question. You might want to reconsider whether all the extra printing is really that useful.

You might also want to elaborate a bit more on what exactly you are trying to achieve - there might be a better way. For example if you are running a script whose output is parsed and which may end with an error, which however is detectable from its output, you'll want to add true after the script execution (or as the last command that is run before the script exits for good) - that will make sure your session exits successfully (i.e. with zero exit status) and the "echo SSH_NOK" isn't called.

peterph
  • 30,838
1

What you want cannot be done. If you stay in the new server, you don't execute the part of the command to get the status echo until after you exit the server. That's how SSH works. If you see the new hostname in your prompt, then you know it worked and you're on the target server.

John
  • 17,011
  • This line is part of a much larger script. I need it to be executed this way. peterph answer is pretty good and maybe will do. – Nir Oct 04 '13 at 14:24
1

You need to handle the output from the echo 2>&1.

Example

$ ssh -q skinner "echo 2>&1"

$

Here's what I would do, using one of my hosts, skinner:

$ ssh -q skinnerrr "echo 2>&1 > /dev/null"  && echo SSH_OK || echo SSH_NOK
SSH_NOK

$ ssh -q skinner "echo 2>&1 > /dev/null"  && echo SSH_OK || echo SSH_NOK
SSH_OK
slm
  • 369,824
1

you could setup a function on the source machine to indicate in the title bar where you are at: This example is for bash ! adapt it to your needs (beware that the order of function/alias/path may become alias/function/path, that the internal command command may not exist (or may bypass not the thing you want), etc. In bash, it should work even on very old bash (like 2.05b ...)

In your .profile file, for example, add those lines (but please test before) :

# 1) define a prompt showing both in the title of the window/putty AND on the prompt :
#   who you are, on what machine, and where (which dir) :
PS1="\$(echo -ne '\[\033]0;#'\${USER}@\${HOSTNAME}:\${PWD}'\007\]')### \${USER}@\${HOSTNAME}:\${PWD} #"

#and 2) redefine "ssh" to be a function that also indicate where you go to:
ssh () { #the function do ssh, but also indicate where it ssh to (in the title of the window)
   #change the title
   echo -ne "\033]0;In ssh $@\007";  #set xterm title (and Putty too)
   #do the ssh here
   command ssh "$@"     #note: 'command something' will bypass both a function AND a alias named 'something', whereas \something would just bypass an alias named 'something'
   #put back the title to something meaningful, once we finished the ssh
   echo -ne "\033]0;#${USER}@${HOSTNAME}:${PWD}\007";  #set xterm title (and Putty too)
}

That way, in both your prompt and title you have the info of where you are (thanks to PS1), and also when you ssh somewhere you know where you end up to (and when you finish the prompt and title reverse to where you are immediately and not just at the next prompt)

1

If your goal is to first make sure that you can connect to the remote server, and then do a bunch of stuff locally and remotely, then my recommendation is to

  1. establish a remote connection (and not close it);
  2. do your stuff.

To establish a remote connection, run a master session. Then, to do remote stuff, piggyback onto the existing connection. Slave connections use the existing TCP stream, they do not require any extra authentication, so they will succeed (and be fast to establish) except of course if the network or the remote host goes down.

ssh_control=$(mktemp -d)/ssh.control
ssh -M -o ControlMaster=yes -o ControlPath="$ssh_control" -n user1@server1
if [ $? -eq 0 ]; then
  do_some_local_stuff
  ssh -o ControlMaster=yes -o ControlPath="$ssh_control" -n user1@server1
  do_some_more_local_stuff
  if ! ssh -O check -o ControlMaster=yes -o ControlPath="$ssh_control" -n user1@server1; then
    echo 'Uh-oh! The SSH connection died abruptly.'
  fi
fi
ssh -O exit -o ControlMaster=yes -o ControlPath="$ssh_control" -n user1@server1
rm "$ssh_control"
rmdir "${ssh_control%/*}"
0

Quoted from your other question :

Because this can take a while, I prefer not to use SSH - rather I prefer to check first if I can connect and if so then try to connect through SSH.

You finally decided to go for testing with SSH.

If you're testing the connection through SSH before actually connecting through SSH, then you're wasting your time : it will take the same time for the test to fail than for the actual connection attempt to fail anyway. Just try to connect directly.

That being said, if you absolutely need to test the connection before to connect, I guess you can do something like this :

CONNECTION_TO_TEST="user1@server1"
ssh -q $CONNECTION_TO_TEST echo 2>/dev/null && echo SSH_OK && ssh $CONNECTION_TO_TEST || echo SSH_NOK