9

How can I automatize this task?

1) You are at A. 2) You ssh into B. 3) You run a script at B, that needs a parameter known at A.

First, I thought perhaps I could send the value when I opened the connection with ssh. Then, probably simpler, between 1) and 2), scp the entire script to the same location at B (replacing the old one). But still, how do I execute the script at B? (That is, how to automatize that last step. Of course, I could run it manually after ssh.)

Another thought, maybe discard of ssh altogether - I have a web page at B, so could the script somehow be invoked through an "under the hood" web interface?

Or would you do it in an altogether different way?

1

4 Answers 4

12
myparameter=foobar
ssh user@server "myscript $myparameter"

This will execute myscript foobar on the server.

4
  • Simple as that! Works great. (I had to put a "./" before the script name because otherwise it looked for ~/.elm/aliases.) Jul 15, 2012 at 23:19
  • 7
    As a small warning, the use of double quotation marks (") as opposed to single ones (') is important here. Using double means that the shell on your local machine will expand the variable, then execute the ssh command. If single ones were to be used the local shell would not touch the command, which is sent on verbatim but is still be expanded in the remote shell. Jul 16, 2012 at 1:14
  • 4
    Note that if $myparameter contains spaces, it will split on the server side. Bash's printf has a %q format that you could use. I have some example code, but it does not fit here. I'll create a new answer for it.
    – janmoesen
    Jul 16, 2012 at 13:17
  • to me it does not work.
    – gdm
    Nov 10, 2023 at 14:59
8

(This is a follow-up to my comment on the accepted answer.)

Note that if $myparameter contains spaces, it will split on the server side. Bash's printf has a %q format that you could use. Example:

$ myparameter='hello; rm somefile'
$ ssh user@server "echo $myparameter"
hello
rm: cannot remove `somefile': No such file or directory

$ ssh user@server "echo $(printf '%q' "$myparameter")"
hello; rm somefile
1
  • if you want to forward $@, use args=$(printf ' %q' "$@"), then ssh ... "$args" (note a space prior %q).
    – Ninh Pham
    Jan 13, 2023 at 14:28
1

If it is safe to assume that $myparameter will not contain single quotes (otherwise see here or use the printf '%q' ... solution by janmoesen), you can just put single quotes around $myparameter to avoid the split-on-space problem on the server side.

myparameter="foo \" bar"
#myparameter="foo \" ' bar"

ssh localhost "set -xv; printf '%s\n' myscript '${myparameter}'"
ssh localhost "set -xv; echo $(set -xv; printf '%q' "$myparameter")"
1

I hesitate to answer a 10-yo question, especially when there's already a perfectly good answer, but note that the 'remote' script doesn't actually need to be on B at all. This (a) makes the parameter substitution trivial, and (b) removes the complication of whether it's a good idea to have the script on the remote system at all (security issues/whatever).

The alternative is just to run ssh with here doc input. In this case, the parameter substitution is done locally, and not on the remote system (as long as you don't quote the doc delimiter, in this case EOF):

portnum=1234
[email protected]
mydir=/var/www/bar
param=foo

ssh -p$portnum $target /bin/bash <<EOF
  set -e;
  cd $mydir;
  # create remote 3-character file '/var/www/bar/myfile' containing 'foo'
  echo -n $param > myfile
EOF

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .