首页 文章

如何使用SSH在远程计算机上运行shell脚本?

提问于
浏览
1055

我必须在远程机器上运行shell脚本(windows / Linux) .

我在机器A和B上配置了SSH . 我的脚本在机器A上,它将在远程机器B机器上运行我的一些代码 .

本地和远程计算机可以是基于Windows或Unix的系统 .

有没有办法使用plink / ssh运行?

13 回答

  • -23

    我用这个在远程机器上运行shell脚本(在/ bin / bash上测试):

    ssh deploy@host . /home/deploy/path/to/script.sh
    
  • 133

    假设您想要从“本地”机器自动执行此操作,而无需手动登录“远程”机器,您应该查看一个名为Expect的TCL扩展,它专为这种情况而设计 . 它的主页下面看起来有点蹩脚,但不要让它劝阻你;我还提供了一个用于通过SSH登录/交互的脚本的链接 .

    http://expect.nist.gov/

    http://bash.cyberciti.biz/security/expect-ssh-login-script/

  • 26

    尝试运行 ssh user@remote sh ./script.unx .

  • 0

    这个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"
    
  • 526

    如果你想执行这样的命令 temp=ls -aecho $temp 命令``会导致错误 .

    下面的命令将解决这个问题 ssh user@host ''' temp=ls -aecho $temp '''

  • 9

    首先,使用scp将脚本复制到Machine B.

    [user @ machineA] $ scp / path / to / script user @ machineB:/ home / user / path

    然后,只需运行脚本

    [user @ machineA] $ ssh user @ machineB“/ home / user / path / script”

    如果您已为脚本提供了可执行权限,则此方法将起作用 .

  • 9

    另外,如果要从目标主机中选择它们,请不要忘记转义变量 .

    这让我过去了 .

    例如:

    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}'"
    

    正确打印出“你好” .

  • 1

    如果您尝试使用 plinkssh 在远程Linux机器上运行脚本,则此处(https://stackoverflow.com/a/2732991/4752883)的答案非常有用 . 如果脚本在 linux 上有多行,它将起作用 .

    但是,如果您尝试运行位于本地 linux/windows 计算机上的批处理脚本,并且您的远程计算机是 Windows ,并且它包含多行使用

    plink root@MachineB -m local_script.bat

    不会工作 .

    只会执行脚本的第一行 . 这可能是 plink 的限制 .

    解决方案1:

    要运行多行批处理脚本(特别是如果它相对简单,包含几行):

    如果您的原始批处理脚本如下所示

    cd C:\Users\ipython_user\Desktop 
    python filename.py
    

    您可以使用"&&"文件中的"&&"分隔符将行组合在一起,如下所示: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`
    

    解决方案2:

    如果批处理脚本相对复杂,最好使用封装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
    
  • 94
    <hostA_shell_prompt>$ ssh user@hostB "ls -la"
    

    这将提示您输入密码,除非您已将hostA用户的公钥复制到用户.ssh目录主页上的authorized_keys文件中 . 这将允许无密码身份验证(如果在ssh服务器的配置上被接受为auth方法)

  • 0

    这是一个老问题,杰森的答案很好,但我想补充一点:

    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
    

    (我认为这应该有效)

    另见http://tldp.org/LDP/abs/html/here-docs.html

  • 0

    如果计算机A是Windows框,则可以将Plink(PuTTY的一部分)与-m参数一起使用,它将在远程服务器上执行本地脚本 .

    plink root@MachineB -m local_script.sh
    

    如果机器A是基于Unix的系统,您可以使用:

    ssh root@MachineB 'bash -s' < local_script.sh
    

    您不必将脚本复制到远程服务器以运行它 .

  • 1062

    这是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命令 . 瞧 .

  • 217

    我已经开始使用Fabric进行更复杂的操作 . Fabric需要Python和其他几个依赖项,但仅限于客户端计算机上 . 服务器只需要一个ssh服务器 . 我发现这个工具比传递给SSH的shell脚本更强大,值得设置的麻烦(特别是如果你喜欢用Python编程) . Fabric处理在多个主机(或某些角色的主机)上运行脚本,有助于促进幂等操作(例如向配置脚本添加一行,但如果它已经存在则不行),并允许构造更复杂的逻辑(例如Python)语言可以提供) .

相关问题