2

I've heard multiple answers of rights and wrongs and I still don't know if its possible. I ssh to a server then want to run a block of script.

while read server <&3; do   #read server names into the while loop    
serverName=$(uname -n)
 if [[ ! $server =~ [^[:space:]] ]] ; then  #empty line exception
    continue
 fi   
 echo server on list = "$server"
 echo server signed on = "$serverName"
 if [ $serverName == $server ] ; then #makes sure a server doesn't try to ssh to itself
    continue
 fi
    echo "Connecting to - $server"
    ssh "$server"   #SSH login
    echo Connected to "$serverName"
    exec < filelist.txt
    while read updatedfile oldfile; do
    #   echo updatedfile = $updatedfile #use for troubleshooting
    #   echo oldfile = $oldfile   #use for troubleshooting
               if [[ ! $updatedfile =~ [^[:space:]] ]] ; then  #empty line exception
                continue # empty line exception
               fi
               if [[ ! $oldfile =~ [^[:space:]] ]] ; then  #empty line exception
                continue # empty line exception
               fi 
            echo Comparing $updatedfile with $oldfile
            if diff "$updatedfile" "$oldfile" >/dev/null ; then
                echo The files compared are the same. No changes were made.
            else
                echo The files compared are different.
                cp -f -v $oldfile /infanass/dev/admin/backup/`uname -n`_${oldfile##*/}_$(date +%F-%T)
                cp -f -v $updatedfile $oldfile 
            fi          
    done        
 done 3</infanass/dev/admin/servers.txt

I want to run the block of code after sshing to the servers.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
mkrouse
  • 939
  • What part of the above script do you want to run on the target machine inside the SSH session? – John Jul 16 '13 at 14:43
  • Everything after the ssh connection to the second to last done. – mkrouse Jul 16 '13 at 14:46
  • 2
    I would split the script into 2 and have the first be the controller, looping to each machine, and scp the 2nd script to each system and then ssh <mach> script to run it . – slm Jul 16 '13 at 15:02
  • 2
  • I answered pretty similar to this once. If anything in here seems like it might be remotely useful and you'd like me to expand on it just ask - http://unix.stackexchange.com/a/120863/52934 – mikeserv Apr 04 '14 at 02:53

3 Answers3

2

The problem you're having currently is that the SSH connection "pauses" the script, and the script resumes with the echo Connected to "$serverName" line only after the SSH session exits.

As I see it, you have two options. (There are probably more, but these are the two I can think of currently.)

Option one is to use expect to start an SSH session you can control through the script, effectively sending commands back and forth from the master script to the SSH session. Option two is to put the block you want to run remotely on the remote server as a different script, and run SSH in a non-interactive way: ssh $server $script-to-run.

John
  • 17,011
1

If you're absolutely convinced that you want to structure this as a single script you can make use of a HEREDOC when you open your connection to the remote ssh server.

For example:

$ ssh user@server << EOT

...
commands
...

EOT
slm
  • 369,824
  • it still wont work for some reason – mkrouse Jul 17 '13 at 14:52
  • @mkrouse - you can't have spaces before the string "EOT" which closes the block of the HEREDOC. Can you paste what you tried on pastebin, or update your question with the details? – slm Jul 17 '13 at 18:39
1

Alternatively, simple echo to pipe and then execute all from stdin.

echo " \
uname -a; \
whoami; \
uname " \
| ssh -l root localhost 'cat | sh -'
MAQ
  • 980