2013-03-06 46 views
6

我想在远程机器上依次执行几个命令,而后面的一些命令依赖于以前的命令。在一个最简单的例子,我得到这个:是否可以在远程ssh命令中使用变量?

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 

对于位的背景资料,是我真正想要做的是拼凑的路径和启动的Java应用程序:

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. 

这样,每当jabref被更新到服务器上的新版本时,我就不必手动更新jar文件的路径。 jabref可执行文件不带参数,但是用java -jar启动它,这就是为什么我必须稍微调整一下路径。

目前,我有命令的列表中一个单独的脚本文件,并调用

ssh my_server 'nohup sh -c "((my_script.sh &/dev/null) &)"' & 

其工作原理,但由于SSH调用已里面一个脚本文件,它会是不错的一切融合在一起。

回答

6

从chepner的一些灵感,我现在有一个解决方案,但只有在从bash shell或bash脚本调用时才有效。它不适用于tcsh。

ssh my_server "bash -c 'echo this is \$HOSTNAME; abc=2; echo abc is \$abc;'" 

在此基础上,下面的代码是一个运行的JabRef在远程服务器上(虽然X-转发默认和密码认证用户无法分辨出它是远程)本地脚本:

#!/bin/bash 
if [ -f "$1" ] 
then 
    fname_start=$(echo ${1:0:4}) 
    if [ "$fname_start" = "/tmp" ] 
    then 
     scp $1 my_server:$1 
     ssh my_server "bash -c 'source load_module jdk; source load_module jabref; java_exe=\$(which java); jabref_exe=\$(which jabref); jabref_dir=\$(echo \${jabref_exe%/bin/jabref});eval \$(java -jar \$jabref_dir/jabref.jar $1)'" & 
    else 
     echo input argument must be a file in /tmp. 
else 
    echo this function requires 1 argument 
fi 

这是1行脚本load_module,因为modulecmd设置了环境变量,我无法弄清楚如何在没有脚本的情况下做到这一点。

eval `/path/to/modulecmd bash load $1`; 

我也看了here文档,通过How to use SSH to run a shell script on a remote machine?http://tldp.org/LDP/abs/html/here-docs.html启发。好的部分是它甚至可以从tcsh起作用。我从命令行得到了这个工作,但不是在脚本中。这可能很容易修复,但我现在有一个解决方案,所以我很高兴:-)

ssh my_server 'bash -s' << EOF 
echo this is \$HOSTNAME; abc=2; echo abc is \$abc; 
EOF 
6

在这个例子中

ssh my_server "echo this is my_server; abc=2;" 

abc被设置在远程端,那么为什么不是你的本地计算机上设置应该是清楚的。

在下面的例子中,

ssh my_server "echo this is my_server; abc=2; echo abc is $abc" 

当地壳试图在论证扩大$abc之前它曾经被发送到远程主机。如你预期有轻微的修改将工作:

ssh my_server 'echo this is my_server; abc=2; echo abc is $abc' 

单引号阻止试图扩大$abc当地的外壳等的文字文本它使远程主机。


要最终解决您的真正的问题,试试这个:

jabref_dir=$(ssh my_server 'jabref_exe=$(which jabref); jabref_dir=$(dirname $jabref_exe); 
       java -jar $jabref_dir/../jabref.jar > /dev/null; echo $jabref_dir') 

这将在远程服务器上运行引号的字符串作为命令,并输出只有一个字符串:$jabref_dir。该字符串被捕获并存储在本地主机上的变量中。

+0

谢谢,这让我走上正轨。通过引号或'\ $'防止扩展是关键。事实证明,服务器上的默认shell是tcsh,这是'abc = 2'不起作用的另一个原因。 – craq 2013-03-11 12:58:56

+0

很棒的回答。我使用Jenkins和SSH Agent插件,它像一个魅力。 – 2017-06-21 16:21:47

相关问题