nullPointer
nullPointer

Reputation: 4574

bash run multiple commands on remote hosts via ssh

I am trying to connect to multiple hosts in a loop and run few commands/scripts via ssh, and store results in local var. I am using a here doc but I am a bit confused on whether it should be quoted or not, as I am using a mix of local vars and remotely declared vars. What would be the proper syntax for this ? What do I need to escape?

for host in $HOSTS; do
   RESULT+=$(ssh -T $host <<EOF   
   H=`dirname $HOME`
   M=`mount | grep $H | grep nfs`
   [[ "$M" ]] && MYFILE=$WD/file1 ||  MYFILE=$WD/file2
   cd $WD && monit.sh $MYFILE
EOF
   )
done

$RESULT and $WD are local vars, while the others are remote. The result with the above is that local vars have the expected values, while all the remotely declared vars are empty ($H , $M , $MYFILE..) If I enclose EOF in single quotes, the result is somehow reversed : $WD is empty, while $H and $M get proper values ($MYFILE also but without the $WD part)

Many thanks

Upvotes: 1

Views: 867

Answers (2)

mayur murkya
mayur murkya

Reputation: 149

You can use below bash script:

for s in $(cat host.txt); do
   ssh root@${s} 'bash -s' < /tmp/commands.sh
done

Upvotes: -1

Gordon Davisson
Gordon Davisson

Reputation: 126048

Short answer: escape (with a backslash) every $ and backtick that you want interpreted on the remote computer. Actually, I'd recommend replacing the backticks with $( ) (and then escaping the $). I haven't tested, but this should do it:

for host in $HOSTS; do
   RESULT+=$(ssh -T $host <<EOF   
   H=\$(dirname \$HOME)
   M=\$(mount | grep \$H | grep nfs)
   [[ "\$M" ]] && MYFILE=$WD/file1 ||  MYFILE=$WD/file2
   cd $WD && monit.sh \$MYFILE
EOF
   )
done

Without the escapes, everything was getting interpreted by the local shell before it was sent to the remote system. When you quoted EOF, that told the local shell not to do any interpretation at all, so the local variable ($WD) didn't get substituted.

Upvotes: 2

Related Questions