【问题标题】:fabric cannot execute remote command on windowsFabric 无法在 Windows 上执行远程命令
【发布时间】:2014-04-25 15:13:26
【问题描述】:

我正在使用fabric 在远程Windows 7 系统上运行一些命令。我所做的是:

env.hosts=['192.168.91.235']
env.user='test'
env.password='123456'

def test_windows():
    run("ifconfig",shell=False)
    pass

它适用于“ipconfig”并输出远程系统的网络信息,所以我确定 ssh 连接正常。但它不适用于我尝试过的任何其他命令,例如“cd”、“echo hello”。错误是:

out:无法在远程系统上执行命令或 shell:无法执行进程。

我想远程运行一个 Windows shell 脚本,我应该这样做吗?

附:如果我通过 putty 连接 Windows,命令“cd”“echo hello”就可以工作。

[更新]

我意识到fabric正在使用env.shell来解释我传递的命令,现在我的问题是:可以为fabric env.shell指定一个windows shell吗?以及如何?

[再次更新]

我正在将“cmd.exe”分配给 env.shell,但它一直在执行“cmd.exe”。经过几次尝试env.shell="cmd.exe /c" 最终工作。现在我可以通过结构远程执行direcho

[终于解决后更新:]

我不确定我的解决方案是否有缺陷,直到现在它运行良好。

我的解决方案是在 windows 上使用 msys + 在 linux 上使用 fabric + 在 windows 上使用 freesshd 作为 sshserver。

windows 上的 msys 提供了“bash”,正如 Andrew Walker 下面提到的,fabric 期望“bash”并在其上表现出色。尽管在上面的 [再次更新] 中,fabric 也可以使用cmd.exe /c 并在其上执行 windows 命令。

要将 msys bash/shell 分配给结构,用户应该具体告诉 env 如何找到 bash

env.shell='cmd.exe /c c:/msys/1.0/bin/sh.exe -l -c'

cmd.exe /c告诉fabric下面的字符串应该在cmd.exe中作为“命令”执行,/ccmd.exe表示windows cmd上下文中的命令,就像cmd.exe /c "command"

然后c:/msys/1.0/bin/sh -l -c 由 cmd.exe 执行,fabric 正在执行 msys shell。我不确定-l 是做什么的,没有-l,msys shell 无法在bin 文件夹中找到fakelinuxcommand.exe,所以我得出结论-l 有助于环境。 -ccmd.exe /c中的/c类似,表示下面的字符串是c:/msys/1.0/bin/sh的命令,所以下面传给ssh客户端的东西在msys shell中作为命令执行。

一个集成的例子来说明:

env.password='123456'
env.user='test'
env.hosts=['test@192.168.91.238']
env.shell='cmd.exe /c c:/msys/1.0/bin/sh.exe -l -c'

def run_shell_command(command):
    return run(command,pty=False)

函数 run_shell_command 中的参数command 将与 env.shell 连接并由 msys shell 执行。

[我的结论]

我认为如果没有“类似 bash”的伪终端,fabric 就无法工作。在【再次更新】中,linux中的fabric可以在远程windows的cmd.exe中执行命令。在某些仅存在远程 windows 的情况下,这就足够了。 msys 提供了一个 linux bash 允许我在远程窗口和远程 linux 上从本地 linux 执行相同的 shell 脚本。

【问题讨论】:

    标签: shell fabric msys


    【解决方案1】:

    我同意 Martian Puss 的结论,即“Fabric 可以在没有 'bash-like' shell 的情况下工作”。

    我已将 FreeSSHd 软件安装到我的 Windows 7 机器中(作为服务运行),并且我已授予“sistemas”用户访问 Windows shell 的权限。

    然后,可以使用以下 Fabric 代码在该 shell 上远程调用命令(如 systeminfo):

    from fabric.api import env, run
    
    env.hosts=["sistemas@cliente03"]
    def test_win():
        run("systeminfo", shell=False, pty=False)
    

    请特别注意 shell=False 参数,这是使其正常工作的关键。

    如果我们运行它,这就是我们得到的:

    [sistemas@cliente01 ~]$ fab test_win
    [sistemas@cliente03] Executing task 'test_win'
    [sistemas@cliente03] run: systeminfo
    [sistemas@cliente03] Login password for 'sistemas': 
    [sistemas@cliente03] out: 
    [sistemas@cliente03] out: Host Name:                 RP_CLIENTE03
    [sistemas@cliente03] out: OS Name:                   Microsoft Windows 7 Professional 
    [sistemas@cliente03] out: OS Version:                6.1.7601 Service Pack 1 Build 7601
    [sistemas@cliente03] out: OS Manufacturer:           Microsoft Corporation
    [sistemas@cliente03] out: OS Configuration:          Standalone Workstation
    ...
    [sistemas@cliente03] out: 
    
    
    Done.
    Disconnecting from cliente03... done.
    

    【讨论】:

    • 那个答案应该是正确的,因为解决了我的问题和 OP 的问题。
    【解决方案2】:

    Fabric 确实希望远程机器上有一个 bash(或至少类似于 bash)的 shell。

    让fabric 在远程Windows 机器上运行命令的最简单方法是安装适当的shell。例如,cygwin 的安装默认包含这样的 shell。

    【讨论】:

    • 我非常感谢您的回答,尽管 cygwin 不能完美地满足我们的需求。我已经在问题描述中更新了让 cmd.exe 正常工作的方法。还是谢谢你。
    • 感谢您的支持。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    相关资源
    最近更新 更多