Linux 如何使用参数通过ssh执行远程命令?
在myLinux 如何使用参数通过ssh执行远程命令?,linux,bash,ssh,Linux,Bash,Ssh,在my.bashrc中,我定义了一个稍后可以在命令行上使用的函数: function mycommand() { ssh user@123.456.789.0 cd testdir;./test.sh "$1" } 使用此命令时,仅在远程主机上执行cd命令;test.sh命令在本地主机上执行。这是因为分号分隔了两个不同的命令:ssh命令和test.sh命令 我尝试如下定义函数(注意单引号): 我试图将cd命令和test.sh命令放在一起,但是参数$1没有解析,与我给函数的内容无关。它总
.bashrc
中,我定义了一个稍后可以在命令行上使用的函数:
function mycommand() {
ssh user@123.456.789.0 cd testdir;./test.sh "$1"
}
使用此命令时,仅在远程主机上执行cd
命令;test.sh
命令在本地主机上执行。这是因为分号分隔了两个不同的命令:ssh
命令和test.sh
命令
我尝试如下定义函数(注意单引号):
我试图将cd
命令和test.sh
命令放在一起,但是参数$1
没有解析,与我给函数的内容无关。它总是试图执行命令
./test.sh $1
在远程主机上
如何正确定义
mycommand
,使脚本test.sh
在更改为目录testdir
后在远程主机上执行,并能够将给定给mycommand的参数传递给test.sh
?改为:
function mycommand {
ssh user@123.456.789.0 "cd testdir;./test.sh \"$1\""
}
您仍然需要将整个命令作为单个字符串传递,但是在单个字符串中,您需要在将其发送到ssh之前扩展$1
,因此您需要使用“”
更新
另一种正确的方法是使用printf%q
正确引用参数。这将使参数能够安全地进行分析,即使它包含空格、单引号、双引号或任何其他可能对shell有特殊意义的字符:
function mycommand {
printf -v __ %q "$1"
ssh user@123.456.789.0 "cd testdir;./test.sh $__"
}
- 使用
函数
声明函数时,不需要使用()
- 不要仅仅因为你是一个吹毛求疵的人就对它进行反驳
恢复旧线程,但这一相当干净的方法没有列出
function mycommand() {
ssh user@123.456.789.0 <<+
cd testdir;./test.sh "$1"
+
}
函数mycommand(){
sshuser@123.456.789.0这是一个在AWS云上工作的示例。场景是,从autoscaling启动的某些计算机需要在另一台服务器上执行某些操作,通过SSH传递新生成的实例DNS
# Get the public DNS of the current machine (AWS specific)
MY_DNS=`curl -s http://169.254.169.254/latest/meta-data/public-hostname`
ssh \
-o StrictHostKeyChecking=no \
-i ~/.ssh/id_rsa \
user@remotehost.example.com \
<< EOF
cd ~/
echo "Hey I was just SSHed by ${MY_DNS}"
run_other_commands
# Newline is important before final EOF!
EOF
#获取当前机器的公共DNS(特定于AWS)
MY_DNS=`curl-shttp://169.254.169.254/latest/meta-data/public-hostname`
ssh\
-o StrictHostKeyChecking=否\
-i~/.ssh/id\u rsa\
user@remotehost.example.com \
我正在使用以下命令从本地计算机远程执行命令:
ssh -i ~/.ssh/$GIT_PRIVKEY user@$IP "bash -s" < localpath/script.sh $arg1 $arg2
ssh-i~/.ssh/$GIT_PRIVKEY user@$IP“bash-s”
这与要点无关,但您可能希望使用&&
而不是分号来连接远程主机上执行的命令:cd testdir&&&./test.sh“$1”
。使用该形式(因为在bash中对&
短路的评估),如果cd
失败,第二个命令将不会执行,您也不会无意中在user
的homedir中运行另一个test.sh
。@JoSo是的,这是它的基础,因此根据使用情况,用户可以选择清理他需要的参数。关于basicssh
可能没有更好的方法-un首先进行文件传输的次数越少,等等。@JoSo是的,更好的方法是定义一个quote函数,如quote(){printf''%q'“$1”}
,然后执行sshuser@host“cd testdir;/test.sh$(引用“$1”)”
@augurar,差不多了,但是%q
结果是自引的;在它们周围加上文字引号是不必要的,也不正确的。printf-v arg_str“%q'$1”sshuser@host“cd testdir;/test.sh$arg\u str”
就足够了。@CharlesDuffy为什么需要添加空格?@konsolebox,就目前的情况而言,不需要,但是如果添加更多的参数,而不是将它们全部弄脏,则习惯用法会扩展。如果$1
将扩展为具有“
和可扩展字符,如$
和`
。它不会“失败”。它的效果与使用参数执行任何非ssh命令的效果相同。OP没有要求上双转义参数的课。只是如何让他的第二个命令执行[whatever]参数。如果用户询问如何通过ssh执行某些操作,那么期望任何答案都能涵盖特定于ssh的警告(即在本地运行代码时不存在的警告)。双重扩展(以及由相同原因导致的外壳注入漏洞)在这些警告中,cd testdir;/test.sh“$1”不存在
直接在本地shell中运行,但确实存在给定的代码。我不认为你会对显示SQL注入漏洞的数据库问题给出一个答案,但有人通过mycommand'$(rm-rf~)'运行任意远程代码的可能性同样严重。(…问题是,使代码安全所需的更改非常小:printf-vargv_str“%q'”$@“sshuser@host“bash-s$argv_str”
ssh -i ~/.ssh/$GIT_PRIVKEY user@$IP "bash -s" < localpath/script.sh $arg1 $arg2