什么是最简洁的方式来在Bash中运行多个命令?
我已经设置了一个ssh代理,并且可以在Bash脚本中的外部服务器上运行命令,如下所示:
ssh blah_server "ls; pwd;"
现在,我真正想做的是在外部服务器上运行很多长命令。 把所有这些引用在引号之间是相当难看的,为避免这种情况,我宁愿多次避免ssh'ing。
那么,有没有办法一次性把它放在括号内呢? 我正在寻找的东西沿线:
ssh blah_server ( ls some_folder; ./someaction.sh; pwd; )
基本上,只要干净,我都会很满意。
编辑
为了澄清,我正在谈论这是一个更大的bash脚本的一部分。 其他人可能需要处理脚本,所以我想保持清洁。 我不想有一个像下面这样的行的bash脚本:
ssh blah_server "ls some_folder; ./someaction.sh 'some params'; pwd; ./some_other_action 'other params';"
因为这是非常难看和难以阅读。
如何在这里打一个文件 :
ssh otherhost << EOF ls some_folder; ./someaction.sh 'some params' pwd ./some_other_action 'other params' EOF
为了避免@Globalz在评论中提到的问题,你可以(取决于你在远程站点上做什么),用第一行代替
ssh otherhost /bin/bash << EOF
请注意,您可以在Here文档中进行variablesreplace,但是您可能需要处理引用问题。 例如,如果引用“限制string”(即上面的EOF
),则不能进行variablesreplace。 但是没有引用限制string,variables被replace。 例如,如果您在shell脚本中定义$NAME
上面的$NAME
,则可以这样做
ssh otherhost /bin/bash << EOF touch "/tmp/${NAME}" EOF
它会在目标otherhost
上创build一个文件,其名称是你分配给$NAME
。 关于shell脚本引用的其他规则也适用,但是这里太复杂了。
在本地编辑你的脚本,然后将其pipe理到ssh中,例如
cat commands-to-execute-remotely.sh | ssh blah_server
其中commands-to-execute-remotely.sh
看起来像上面的列表:
ls some_folder ./someaction.sh pwd;
我看到两种方式:
首先你做一个这样的控制套接字:
ssh -oControlMaster=yes -oControlPath=~/.ssh/ssh-%r-%h-%p <yourip>
并运行你的命令
ssh -oControlMaster=no -oControlPath=~/.ssh/ssh-%r-%h-%p <yourip> -t <yourcommand>
这样你就可以编写一个ssh命令,而不需要重新连接服务器。
第二个是dynamic生成脚本, scp
并运行。
为了匹配您的示例代码,您可以将您的命令封装在单个或双个qoutes中。 例如
ssh blah_server " ls pwd "
这也可以如下完成。 把你的命令放在一个脚本中,让我们命名为commands-inc.sh
#!/bin/bash ls some_folder ./someaction.sh pwd
保存文件
现在在远程服务器上运行它。
ssh user@remote 'bash -s' < /path/to/commands-inc.sh
从来没有失败过。
SSH和在Bash中运行多个命令。
在string中用分号分隔命令,传递给echo,所有命令都传送到ssh命令中。 例如:
echo "df -k;uname -a" | ssh 192.168.79.134 Pseudo-terminal will not be allocated because stdin is not a terminal. Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda2 18274628 2546476 14799848 15% / tmpfs 183620 72 183548 1% /dev/shm /dev/sda1 297485 39074 243051 14% /boot Linux newserv 2.6.32-431.el6.x86_64 #1 SMP Sun Nov 10 22:19:54 EST 2013 x86_64 x86_64 x86_64 GNU/Linux
把所有的命令放在一个脚本上,它可以运行
ssh <remote-user>@<remote-host> "bash -s" <./remote-commands.sh
一个想法:
将你的长命令包装在一个bash脚本中, scp
到目标服务器,用ssh
执行,并在脚本结尾处有一个“delete-self”命令。
这适用于创build脚本,因为您不必包含其他文件:
#!/bin/bash ssh <my_user>@<my_host> "bash -s" << EOF # here you just type all your commmands, as you can see, ie touch /tmp/test1; touch /tmp/test2; touch /tmp/test3; EOF
最简单的方法来configuration您的系统默认使用单个ssh会话多路复用。
这可以通过为套接字创build一个文件夹来完成:
mkdir ~/.ssh/controlmasters
然后将以下内容添加到.sshconfiguration中:
Host * ControlMaster auto ControlPath ~/.ssh/controlmasters/%r@%h:%p.socket ControlMaster auto ControlPersist 10m
现在,你不需要修改你的任何代码。 这允许多次调用ssh和scp而不创build多个会话,当需要在本地和远程机器之间进行更多的交互时这非常有用。
感谢@总站的回答, http://www.cyberciti.biz/faq/linux-unix-osx-bsd-ssh-multiplexing-to-speed-up-ssh-connections/和https://en.wikibooks.org / wiki / OpenSSH / Cookbook / Multiplexing 。
对于像我这样在这里磕磕绊绊的人 – 我已经成功地转义了分号和换行符:
第一步:分号。 这样,我们不会中断ssh命令:
ssh <host> echo test\;ls ^ backslash!
列出远程主机/主目录(以root身份login),而
ssh <host> echo test;ls ^ NO backslash
列出了当前的工作目录。
下一步:分手线:
v another backslash! ssh <host> echo test\;\ ls
这再次列出了远程工作目录 – 改进的格式:
ssh <host>\ echo test\;\ ls
如果真的比这里更好的文件或引用虚线 – 好吧,不是我决定…
(使用bash,Ubuntu 14.04 LTS。)
使用多行string和多个bash脚本发布的答案不适合我。
- 长的多行string很难维护。
- 单独的bash脚本不保留局部variables。
这是一个function方式ssh和运行多个命令,同时保持本地上下文。
LOCAL_VARIABLE=test run_remote() { echo "$LOCAL_VARIABLE" ls some_folder; ./someaction.sh 'some params' ./some_other_action 'other params' } ssh otherhost "$(set); run_remote"