I'd like to execute several commands in sequence on a remote machine, and some of the later commands depend on earlier ones. In the simplest possible example I get this:
ssh my_server "echo this is my_server; abc=2;"
this is my_server
abc=2: Command not found.
ssh my_server "echo this is my_server; abc=2; echo abc is $abc"
abc: undefined variable
For a bit of background info, what I actually want to do is piece together a path and launch a java application:
ssh my_server 'nohup sh -c "( ( echo this is my_server; jabref_exe=`which jabref`; jabref_dir=`dirname $jabref_exe`; java -jar $jabref_dir/../jabref.jar` $1 &/dev/null ) & )"' &
jabref_dir: Undefined variable.
That way, whenever jabref gets updated to a new version on the server, I won't have to manually update the path to the jar file. The jabref executable doesn't take arguments, but launching it with java -jar
does, which is why I have to juggle the path a bit.
At the moment I have the list of commands in a separate script file and call
ssh my_server 'nohup sh -c "( ( my_script.sh &/dev/null ) & )"' &
which works, but since the ssh call is already inside one script file it would be nice to have everything together.
In this example
abc
is set on the remote side, so it should be clear why it is not set on your local machine.In the next example,
your local shell tries to expand
$abc
in the argument before it is ever sent to the remote host. A slight modification would work as you expected:The single quotes prevent your local shell from trying to expand
$abc
, and so the literal text makes it to the remote host.To finally address your real question, try this:
This will run the quoted string as a command on your remote server, and output exactly one string:
$jabref_dir
. That string is captured and stored in a variable on your local host.With some inspiration from chepner, I now have a solution that works, but only when called from a bash shell or bash script. It doesn't work from tcsh.
Based on this, the code below is a local script which runs jabref on a remote server (although with X-forwarding by default and passwordless authentication the user can't tell it's remote):
and this is the 1-line script load_module, since modulecmd sets environment variables and I couldn't figure out how to do that without sourcing a script.
I also looked at heredocs, inspired by How to use SSH to run a shell script on a remote machine? and http://tldp.org/LDP/abs/html/here-docs.html. The nice part is that it works even from tcsh. I got this working from the command line, but not inside a script. That's probably easy enough to fix, but I've got a solution now so I'm happy :-)