我必须在远程计算机上运行Shell脚本(Windows / Linux)。
我在机器A和B上都配置了SSH。我的脚本在机器A上,它将在远程机器B上运行我的一些代码。
本地和远程计算机可以是Windows或Unix系统。
有没有办法使用plink / ssh来执行此操作?
我必须在远程计算机上运行Shell脚本(Windows / Linux)。
我在机器A和B上都配置了SSH。我的脚本在机器A上,它将在远程机器B上运行我的一些代码。
本地和远程计算机可以是Windows或Unix系统。
有没有办法使用plink / ssh来执行此操作?
Answers:
如果计算机A是Windows机器,则可以将Plink(PuTTY的一部分)与-m参数一起使用,它将在远程服务器上执行本地脚本。
plink root@MachineB -m local_script.sh
如果计算机A是基于Unix的系统,则可以使用:
ssh root@MachineB 'bash -s' < local_script.sh
您无需将脚本复制到远程服务器即可运行它。
sudo
,请运行ssh root@MachineB 'echo "rootpass" | sudo -Sv && bash -s' < local_script.sh
。
HISTCONTROL=ignoreboth or ignorespace
使之
ssh root@MachineB ARG1="arg1" ARG2="arg2" 'bash -s' < local_script.sh
积分将完全转到@chubbsondubs的以下答案。
这是一个古老的问题,Jason的答案很好,但是我想补充一下:
ssh user@host <<'ENDSSH'
#commands to run on remote host
ENDSSH
这也可以与需要用户输入的su和命令一起使用。(请注意'
转义的heredoc)
编辑:由于此答案不断获得一些流量,我将添加更多信息到heredoc的这种出色用法:
您可以使用此语法嵌套命令,这就是嵌套似乎起作用的唯一方式(以合理的方式)
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作为文本发送,它不等待行之间的响应
编辑:我刚刚发现,如果使用,您可以缩进制表符的内部<<-END
!
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
(我认为这应该有效)
<<'ENDSSH'
)周围加上单引号,则不会扩展字符串,也不会评估变量。您也可以使用<<ENDSSH
或<<"ENDSSH"
如果要扩展。
Expect
当您需要自动执行交互式命令(例如FTP)时,可以使用。
另外,如果要从目标主机中提取变量,请不要忘记对变量进行转义。
过去,这让我感到困惑。
例如:
user@host> ssh user2@host2 "echo \$HOME"
打印出/ home / user2
而
user@host> ssh user2@host2 "echo $HOME"
打印出/ home / user
另一个例子:
user@host> ssh user2@host2 "echo hello world | awk '{print \$1}'"
正确打印出“ hello”。
ssh user2@host 'bash -s' echo $HOME /home/user2 exit
for
在ssh
会话中运行的in 循环中,不得对loop变量进行转义。
ssh user2@host2 'echo hello world' | awk '{ print $1 }'
在本地运行Awk脚本。如果远程命令产生了大量的输出,那么您当然要避免将其全部复制回本地服务器。顺便说一句,远程命令周围的单引号避免了任何转义。
这是对YarekT答案的扩展,它结合了嵌入式远程命令和将ENV变量从本地计算机传递到远程主机的功能,因此您可以在远程端参数化脚本:
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之后将所有内容作为remote_command发送。当远程计算机执行命令ARG1和ARG2时,设置了本地值,这要归功于本地命令行评估,该评估在远程服务器上定义了环境变量,然后使用这些变量执行bash -s命令。瞧
ssh user@host "ARG1=\"$ARG1\" ARG2=\"$ARG2\"" 'bash -s' <<'ENDSSH'...
-s
是能够将参数应用于通过stdin生成的脚本。我的意思是,如果您不打算使用它,也可以忽略它。如果您确实使用它,则没有理由使用环境变量:ssh user@host 'bash -s value1 value2' <<< 'echo "$@"'
<hostA_shell_prompt>$ ssh user@hostB "ls -la"
这将提示您输入密码,除非您已将hostA用户的公共密钥复制到用户.ssh目录的目录中的authorized_keys文件中。这将允许无密码身份验证(如果在ssh服务器的配置中被接受为auth方法)
尝试跑步ssh user@remote sh ./script.unx
。
假设您是想从“本地”计算机上自动执行此操作,而无需手动登录“远程”计算机,则应查看一个称为Expect的TCL扩展,它是专门为这种情况而设计的。我还提供了指向脚本的链接,该脚本用于通过SSH登录/交互。
ssh user@hostname ".~/.bashrc;/cd path-to-file/;.filename.sh"
强烈建议您获取环境文件(.bashrc / .bashprofile / .profile)。在远程主机中运行某些命令之前,因为目标主机和源主机的环境变量可能会有所不同。
如果您尝试使用或在远程Linux计算机上运行脚本,则此处的答案(https://stackoverflow.com/a/2732991/4752883)非常有用。如果脚本上有多行,它将起作用。plink
ssh
linux
**但是,如果您尝试运行位于本地linux/windows
计算机上的批处理脚本,而您的远程计算机是Windows
,并且该脚本
由多行组成,请使用**
plink root@MachineB -m local_script.bat
不会工作。
仅脚本的第一行将被执行。这可能是的限制plink
。
要运行多行批处理脚本(尤其是如果它相对简单一些,则由几行组成):
如果您的原始批处理脚本如下
cd C:\Users\ipython_user\Desktop
python filename.py
您可以使用文件中的“ &&”分隔符将这些行组合在一起,如下所示
local_script.bat
:
https : //stackoverflow.com/a/8055390/4752883:
cd C:\Users\ipython_user\Desktop && python filename.py
进行此更改后,您可以按照@ JasonR.Coombs此处指出的那样运行脚本:https : //stackoverflow.com/a/2732991/4752883,其中:
`plink root@MachineB -m local_script.bat`
如果您的批处理脚本相对复杂,则最好使用封装plink命令的批处理脚本以及@Martin https://stackoverflow.com/a/32196999/4752883在此处指出的以下命令:
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\R\R-3.2.1\bin\x64\R.exe" CMD BATCH qidash.R
rem Kill the tunnel
taskkill /im plink.exe
此bash脚本确实将ssh放入目标远程计算机,并在远程计算机上运行一些命令,在运行它之前不要忘记安装Expect(在Mac上brew install expect
)
#!/usr/bin/expect
set username "enterusenamehere"
set password "enterpasswordhere"
set hosts "enteripaddressofhosthere"
spawn ssh $username@$hosts
expect "$username@$hosts's password:"
send -- "$password\n"
expect "$"
send -- "somecommand on target remote machine here\n"
sleep 5
expect "$"
send -- "exit\n"
您可以使用runoverssh:
sudo apt install runoverssh
runoverssh -s localscript.sh user host1 host2 host3...
-s
远程运行本地脚本
有用的标志:
-g
对所有主机使用全局密码(单个密码提示),
-n
使用SSH代替sshpass,对公共密钥身份验证很有用
首先,使用scp将脚本复制到计算机B
[user @ machineA] $ scp / path / to / script user @ machineB:/ home / user / path
然后,只需运行脚本
[user @ machineA] $ ssh user @ machineB“ / home / user / path / script”
如果您已授予脚本可执行权限,则此方法有效。