How To Run A For Loop In A Remsh?

Hi all,

I'm trying to remsh to another server and then execute a for loop command there but I'm getting unexpected errors and would appreciate any suggestions.

Ideally what I want to do is this:

for host in `cat host_file`
do
  remsh $host -n "
     cd /home/
     for DATABASE in `ls -d db[1-8]*`
     do
          [execute program] $DATABASE
     done"
done

Now my understanding is that you can't use new lines for remsh logic so the code would have to look like this:

for host in `cat host_file`
do
  remsh $host -n "cd /home/; for DATABASE in `ls -d db[1-8]*`; do; [execute program] $DATABASE;  done"
done

Unfortunately I get the following error:

ksh: syntax error at line 1 : `;' unexpected

So clearly I'm doing something wrong. I've tried chaning the placement of the semi colons but to no avail. :confused:

This may work for you, I've done it in the past.

Enter the command line on your local box:

for i in 1 2 3 
do
   echo $i
done

ctrl/c to break the command (probably won't work locally anyway)
Next recall the command.
-for example in bash: ctrl-up arrow or ksh (with export EDITOR=vi) esc-k
You now have a line that looks like:

for i in 1 2 3 ^Jdo ^Jecho $i ^Jdone

scrape the screen, then paste the command string:

remsh host "for i in 1 2 3 ^Jdo ^Jecho $i ^Jdone"

Don't put a semi-colon after a "do".

$ for i in a b c ; do echo $i ; done
a
b
c
$

My advice. Protecting Shell special characters in a complex "remsh" line will drive you nuts. It is so important to be aware which Shell special characters will be executed on the local computer and which will be executed on the remote computer. It is not impossible to achieve but please bear in mind the next administrator who reads your code.

The professional approach is to first proliferate the script to each of the remote servers and then invoke the script from a "remsh" command.
This approach means that you can test the script while logged in to the remote server.

1 Like

Although I answered the question that was asked, I always do as methyl suggests for any remote commands beyond a simple "uptime" or "date".

I do sometimes type in loops or quick function definitions at the command line locally as I showed in my example. So I stay up to speed on ksh syntax as well. Real example: I was on a broken system and cat and ls didn't work, nor did most commands. So I do a quick:

function mycat { while read l ; do echo "$l" ; done < $1 ; }
function myls { while [ $# -ne 0 ] ; do echo "$1" ; shift; done ;}

and I can look around with commands like "myls /etc/*" and "mycat somefile". It's very handy being able to pull stuff like that out of my hat when I need to.

I'm rather fond of pdsh, which includes pdcp for copying files to/from a large number of nodes.