简体   繁体   English

如何使用参数通过 ssh 执行远程命令?

[英]How to execute a remote command over ssh with arguments?

In my .bashrc I define a function which I can use on the command line later:在我的.bashrc中,我定义了一个稍后可以在命令行上使用的函数:

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

When using this command, just the cd command is executed on the remote host;使用此命令时,只是在远程主机上执行cd命令; the test.sh command is executed on the local host. test.sh命令在本地主机上执行。 This is because the semicolon separates two different commands: the ssh command and the test.sh command.这是因为分号分隔了两个不同的命令: ssh命令和test.sh命令。

I tried defining the function as follows (note the single quotes):我尝试按如下方式定义函数(注意单引号):

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

I tried to keep the cd command and the test.sh command together, but the argument $1 is not resolved, independent of what I give to the function.我试图将cd命令和test.sh命令放在一起,但参数$1没有解析,与我给函数的内容无关。 It is always tried to execute a command总是尝试执行命令

./test.sh $1

on the remote host.在远程主机上。

How do I properly define mycommand , so the script test.sh is executed on the remote host after changing into the directory testdir , with the ability to pass on the argument given to mycommand to test.sh ?我如何正确定义mycommand ,以便在更改为目录testdir后在远程主机上执行脚本test.sh ,并能够将给mycommand的参数传递给test.sh

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. 您仍然必须将整个命令作为单个字符串传递,但在该单个字符串中,您需要在将其发送到ssh之前展开$1 ,因此您需要使用""

Update 更新

Another proper way to do this actually is to use printf %q to properly quote the argument. 实际上这样做的另一种正确方法是使用printf %q来正确引用参数。 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: 即使它有空格,单引号,双引号或任何其他可能对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. 使用function声明函数时, ()不是必需的。
  • Don't comment back about it just because you're a POSIXist. 不要仅因为你是POSIXist而对它发表评论。

Reviving an old thread, but this pretty clean approach was not listed. 恢复旧的线程,但没有列出这个非常干净的方法。

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

This is an example that works on the AWS Cloud. 这是适用于AWS Cloud的示例。 The scenario is that some machine that booted from autoscaling needs to perform some action on another server, passing the newly spawned instance DNS via SSH 方案是,从自动扩展启动的某台计算机需要在另一台服务器上执行某些操作,通过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

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

ssh -i ~/.ssh/$GIT_PRIVKEY user@$IP "bash -s" < localpath/script.sh $arg1 $arg2

A little trick for me, using the "bash -s" they said they allow POSITIONAL ARGS but apparently the $0 is already reserved for whatever reason... Then using twice the same args rocks like so:对我来说是一个小技巧,使用“bash -s”,他们说他们允许 POSITIONAL ARGS 但显然 $0 已经出于某种原因保留了......然后使用两次相同的 args 岩石就像这样:

ssh user@host "bash -s" < ./start_app.sh -e test -e test -f docker-compose.services.yml 

Solution : you want to be able connect to machine remotely using ssh protocol and trigger/run some actions outside.解决方案:您希望能够使用 ssh 协议远程连接到机器并在外部触发/运行一些操作。

on ssh use a -t flag, from documentation:在 ssh 上使用-t标志,来自文档:

-t Force pseudo-terminal allocation.
This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, eg when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, eg when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty. when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty.

formula :公式

ssh -i <key-path> <user>@<remote-machine> -t '<action>'

Example : as administrator I want to be able to connect remotely into ec2 machines and trigger a revert process for a bad deployment on a several machines in a raw, moreover you better implement this action as an automation script that use ips as an arguments and running on different machines in parallel.示例:作为管理员,我希望能够远程连接到 ec2 机器,并针对多台原始机器上的错误部署触发恢复过程,此外,您最好将此操作实现为使用 ips 作为参数并运行的自动化脚本在不同的机器上并行。

ssh -i /home/admin/.ssh/key admin@10.20.30.40 -t 'cd /home/application && make revert'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM