Wrapping ssh inside a script, and passing arbitrary commands to another program

A way to solve this problem, which I presented in a previous post, was found with the help from the gurus on #bash. The easy way to make this work is to save the arguments to a file, one per line, and read them back at the other end. Using bash syntax for arrays "${a[@]}" which quotes every element separately, the original arguments can be reconstructed at the remote end, with the same separation they had at the origin.

Here is the code that does just that:

$ cat ssh-wrapper
#!/bin/bash
tmp=$(mktemp -p $(pwd))
for i; do
  echo $i >>$tmp
done
ssh -t localhost "$(pwd)/remote_script" "$(pwd)" "./prog" "$tmp"
rm -f $tmp

$ cat remote-script
declare -a a
declare i
while read; do
  echo $REPLY
  a[i++]="$REPLY"
done <$3
cd $1 && $2 "${a&#91;@&#93;}"

$ cat prog
#!/bin/bash
eval "$@"
# This program traps INT and queries the user for input
function process_int {
  echo -n "INT> "
  read LINE
  echo $LINE
  exit 2
}
trap process_int SIGINT
sleep 30
$

Now it works as expected for both types of end user quoting:

# Double quotes quoting
$ ./ssh-wrapper "FOO='a b' && echo ' hi' && echo $FOO"
 hi

^CINT> it works!
it works!
Connection to localhost closed.

# Single quotes quoting
$ ./ssh-wrapper 'FOO="a b" && echo " hi" && echo $FOO'
 hi
a b
^CINT> it works too!
it works too!
$
Connection to localhost closed.

If the two hosts were on different file systems, scp could be used to send the arguments over to a file on the remote host. You could even send environment information this way.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: