How to use SSH to run a shell script on a remote machine?
我必须在远程机器上运行shell脚本(windows/linux)。
我在机器A和B上都配置了ssh。我的脚本在机器A上,它将在远程机器B上运行我的一些代码。
本地和远程计算机可以是基于Windows或Unix的系统。
有没有办法用plink/ssh来运行?
如果machineA是一个windows框,您可以将plink(putty的一部分)与-m参数一起使用,它将在远程服务器上执行本地脚本。
1 | plink root@MachineB -m local_script.sh |
如果机器A是基于Unix的系统,则可以使用:
1 | ssh root@MachineB 'bash -s' < local_script.sh |
您不必将脚本复制到远程服务器来运行它。
这是一个老问题,杰森的回答很好,但我想补充一点:
1 2 3 | ssh user@host <<'ENDSSH' #commands to run on remote host ENDSSH |
这也可以用于SU和需要用户输入的命令。(注意,
编辑:由于这个答案一直得到一些流量,我会添加更多的信息到Heredoc的精彩使用中:
您可以用这种语法嵌套命令,这是嵌套工作的唯一方法(以一种明智的方式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ssh user@host <<'ENDSSH' #commands to run on remote host ssh user@host2 <<'END2' # Another bunch of commands on another host wall <<'ENDWALL' Error: Out of cheese ENDWALL ftp ftp.secureftp-test.com <<'ENDFTP' test test ls ENDFTP END2 ENDSSH |
实际上,您可以与一些服务(如telnet、ftp等)进行对话,但请记住,Heredoc只是以文本形式发送stdin,它不等待行之间的响应。
编辑:我刚发现,如果你使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ssh user@host <<-'ENDSSH' #commands to run on remote host ssh user@host2 <<-'END2' # Another bunch of commands on another host wall <<-'ENDWALL' Error: Out of cheese ENDWALL ftp ftp.secureftp-test.com <<-'ENDFTP' test test ls ENDFTP END2 ENDSSH |
(我认为这应该有效)
也看到网址:http://tldp.org/ldp/abs/html/here-docs.html
此外,如果您想从目标主机中提取变量,请不要忘记对它们进行转义。
这在过去已经把我吸引住了。
例如:
1 | user@host> ssh user2@host2"echo \\$HOME" |
打印输出/主页/用户2
虽然
1 | user@host> ssh user2@host2"echo $HOME" |
打印输出/主页/用户
另一个例子:
1 | user@host> ssh user2@host2"echo hello world | awk '{print \\$1}'" |
正确打印"你好"。
这是Yarekt回答的扩展,将内联远程命令与将env变量从本地计算机传递到远程主机相结合,以便在远程端参数化脚本:
1 2 3 4 | ssh user@host ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH' # commands to run on remote host echo $ARG1 $ARG2 ENDSSH |
我发现将所有内容保存在一个脚本中非常有用,因此它非常可读和可维护。
为什么会这样。ssh支持以下语法:
ssh user@host remote_command
在bash中,我们可以在一行上运行命令之前指定要定义的环境变量,如下所示:
ENV_VAR_1='value1' ENV_VAR_2='value2' bash -c 'echo $ENV_VAR_1 $ENV_VAR_2'
这使得在运行命令之前很容易定义变量。在这种情况下,echo是我们正在运行的命令。echo之前的所有内容都定义了环境变量。
因此,我们将这两个特性和Yarekt的答案结合起来,得出:
ssh user@host ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'...
在这种情况下,我们将arg1和arg2设置为本地值。以远程_命令的形式在user@host之后发送所有内容。当远程机器执行命令arg1和arg2时,由于本地命令行评估(它定义了远程服务器上的环境变量),设置了本地值,然后使用这些变量执行bash-s命令。沃伊拉
1 | <hostA_shell_prompt>$ ssh user@hostB"ls -la" |
这将提示您输入密码,除非您已将hosta用户的公钥复制到user.ssh目录的home上的authorized_key s文件。这将允许无密码身份验证(如果在ssh服务器的配置中被接受为auth方法)
我已经开始使用织物进行更复杂的操作。Fabric需要python和一些其他依赖项,但仅在客户机上。服务器只需要一个ssh服务器。我发现这个工具比交付给ssh的shell脚本要强大得多,而且很值得设置麻烦(特别是如果您喜欢用python编程的话)。Fabric处理在多个主机(或某些角色的主机)上运行脚本,有助于促进等幂运算(例如,向配置脚本添加一行,但如果配置脚本已经存在,则不会),并允许构造更复杂的逻辑(例如,Python语言可以提供)。
尝试运行
假设您希望从"本地"机器自动执行此操作,而不需要手动登录"远程"机器,那么您应该查看一个名为Expect的TCL扩展,它是专门针对这种情况设计的。我还提供了一个到脚本的链接,用于通过ssh登录/交互。
https://www.nist.gov/services-resources/software/expect/预计
http://bash.cyberciti.biz/security/expect-ssh-login-script/
我使用这个脚本在远程机器上运行shell脚本(在/bin/bash上测试):
1 | ssh deploy@host . /home/deploy/path/to/script.sh |
如果你想执行这样的命令
temp=`ls -a`
echo $temp
下面的命令将解决这个问题
ssh user@host '''
temp=`ls -a`
echo $temp
'''
这里的答案(https://stackoverflow.com/a/2732991/4752883)如果您试图使用
**但是,如果您尝试运行位于本地
不会工作。
只执行脚本的第一行。这可能是
运行多行批处理脚本(特别是在相对简单的情况下,由几行组成):
如果原始批处理脚本如下
1 2 | cd C:\\Users\\ipython_user\\Desktop python filename.py |
您可以使用"分隔符"将行组合在一起,如下所示
1 | cd C:\\Users\\ipython_user\\Desktop && python filename.py |
在这个更改之后,您就可以运行下面指出的脚本了@jasonr.coombs:https://stackoverflow.com/a/2732991/4752883,网址:
1 | `plink root@MachineB -m local_script.bat` |
解决方案2:
如果批处理脚本相对复杂,则最好使用批处理封装plink命令的脚本,如下所示以下作者:@martin https://stackoverflow.com/a/32196999/4752883:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | rem Open tunnel in the background start plink.exe -ssh [username]@[hostname] -L 3307:127.0.0.1:3306 -i"[SSH key]" -N rem Wait a second to let Plink establish the tunnel timeout /t 1 rem Run the task using the tunnel "C:\\Program Files\ \ -3.2.1\\bin\\x64\ .exe" CMD BATCH qidash.R rem Kill the tunnel taskkill /im plink.exe |
这个bash脚本在目标远程机器上执行ssh,在远程机器上运行一些命令,在运行之前不要忘记安装expect(在mac
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!/usr/bin/expect set username"enterusenamehere" set password"enterpasswordhere" set hosts"enteripaddressofhosthere" spawn ssh $username@$hosts expect"$username@$hosts's password:" send --"$password\ " expect"$" send --"somecommand on target remote machine here\ " sleep 5 expect"$" send --"exit\ " |
首先,使用scp将脚本复制到计算机b
[user@machineA]$ scp /path/to/script user@machineB:/home/user/path
然后,运行脚本
[user@machineA]$ ssh user@machineB"/home/user/path/script"
如果您已授予脚本可执行权限,则此操作将有效。