86

在我.bashrc的定义中,我定义了一个稍后可以在命令行上使用的函数:

function mycommand() {
    ssh user@123.456.789.0 cd testdir;./test.sh "$1"
}

使用该命令时,只是cd在远程主机上执行该命令;该test.sh命令在本地主机上执行。这是因为分号分隔了两个不同的命令:ssh命令和test.sh命令。

我尝试如下定义函数(注意单引号):

function mycommand() {
    ssh user@123.456.789.0 'cd testdir;./test.sh "$1"'
}

我试图将cd命令和test.sh命令放在一起,但参数$1没有得到解决,与我给函数的内容无关。总是试图执行一个命令

./test.sh $1

在远程主机上。

如何正确定义mycommand,以便脚本test.sh在更改到目录后在远程主机上执行testdir,并能够将给定的参数传递mycommandtest.sh

4

5 回答 5

107

Do it this way instead:

function mycommand {
    ssh user@123.456.789.0 "cd testdir;./test.sh \"$1\""
}

You still have to pass the whole command as a single string, yet in that single string you need to have $1 expanded before it is sent to ssh so you need to use "" for it.

Update

Another proper way to do this actually is to use printf %q to properly quote the argument. This would make the argument safe to parse even if it has spaces, single quotes, double quotes, or any other character that may have a special meaning to the shell:

function mycommand {
    printf -v __ %q "$1"
    ssh user@123.456.789.0 "cd testdir;./test.sh $__"
}
  • When declaring a function with function, () is not necessary.
  • Don't comment back about it just because you're a POSIXist.
于 2013-08-29T05:32:48.637 回答
9

我正在使用以下命令在本地计算机上执行远程命令:

ssh -i ~/.ssh/$GIT_PRIVKEY user@$IP "bash -s" < localpath/script.sh $arg1 $arg2
于 2018-12-30T12:19:56.227 回答
7

这是一个适用于 AWS 云的示例。场景是从自动缩放启动的某些机器需要在另一台服务器上执行一些操作,通过 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
于 2018-03-14T10:50:18.797 回答
6

恢复旧线程,但没有列出这种非常干净的方法。

function mycommand() {
    ssh user@123.456.789.0 <<+
    cd testdir;./test.sh "$1"
+
}
于 2014-12-11T00:59:58.777 回答
0

对我来说一个小技巧,使用他们说他们允许 POSITIONAL ARGS 的“bash -s”,但显然 $0 出于某种原因已经被保留了......然后使用两次相同的 args 岩石,如下所示:

ssh user@host "bash -s" < ./start_app.sh -e test -e test -f docker-compose.services.yml 
于 2022-02-18T22:51:19.197 回答