I'm using fabric to run some command on a remote windows 7 system. and what i did was like:
env.hosts=['192.168.91.235']
env.user='test'
env.password='123456'
def test_windows():
run("ifconfig",shell=False)
pass
And it works for "ipconfig" and outputs the network infors of remote system, so i'm sure the ssh connection is OK. But it does not work for any other command i tried, like "cd", "echo hello". The error was :
out: Unable to execute command or shell on remote system: Failed to Execute process.
And i want to run a windows shell script remotely, so should i do?
P.S. the commands "cd" "echo hello" works if i connect the windows via putty.
[Update]
I realize that fabric is using env.shell to interpret the command i passed, now my question is: can is specify a windows shell to fabric env.shell? and how?
[Update again]
I was assigning "cmd.exe" to env.shell and it was stuck at executing "cmd.exe". After a few attempts env.shell="cmd.exe /c"
eventually works. now i can execute dir
, echo
remotely via fabric.
[Update after it's finally solved:]
I'm not sure if my solution is flawed, it goes well till now.
My solution is using msys on windows + fabric on linux + freesshd on windows as sshserver.
msys on windows provides a "bash", as Andrew Walker mentioned below, fabric expects "bash" and performs excellently on it. although in [update again] above, fabric can also live with cmd.exe /c
and execute windows commands on it.
To assign msys bash/shell to fabric, user should tell env specifically how to find the bash
env.shell='cmd.exe /c c:/msys/1.0/bin/sh.exe -l -c'
cmd.exe /c
tell fabric the following string should be execute as a "command" in cmd.exe, /c
after cmd.exe
indicates a command in windows cmd contenxt, it's like cmd.exe /c "command"
then c:/msys/1.0/bin/sh -l -c
is executed by cmd.exe and fabric is executing msys shell. I'm not sure what does -l
do, the msys shell cannot find fakelinuxcommand.exe in bin folder without -l
, so i made the conclusion that -l
helps with the environment. -c
is similar with /c
in cmd.exe /c
, indicating the following string as a command of c:/msys/1.0/bin/sh
, so the following stuff passed to ssh client is executed as a command in msys shell.
An integrate example to make it clear:
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)
the argument command
in function run_shell_command will be concatenate with env.shell and executed by msys shell.
[My Conclusion]
I don't think fabric cannot work without a 'bash like' pseudo terminal. In [update again], fabric in linux can execute command in a remote windows's cmd.exe. And that is enough in some scenarios where only remote winodws are present. msys provides a linux bash to allow me execute same shell scripts on both remote windows and remote linux from a local linux.