pyinvoke / invoke

Pythonic task management & command execution.
http://pyinvoke.org
BSD 2-Clause "Simplified" License
4.41k stars 369 forks source link

Windows - run doesn't have PATH in shell #571

Open apelliciari opened 6 years ago

apelliciari commented 6 years ago

Hi,

on Windows (10) executing this task:

from fabric import task
@task
def docker_test(c):
    c.run("echo %PATH%")
    c.run("docker --version")

gives this output:

%PATH%
docker is not recognized as an internal or external command, an executable program or a batch file

the expected output is:

C:\cmder\bin;C:\cmder\vendor\git-for-windows\cmd;C:\cmder\vendor\conemu-maximus5\ConEmu\Scripts;<a lot of other paths..>
Docker version 18.06.0-ce, build 0ffa825

I'm using Fabric but I think that this is an invoke issue. On Fabric <2.0 it was working perfectly with local.

Is anything I can do to have the PATH in the shell when i use context.run?

bitprophet commented 6 years ago

This depends a lot on exactly what shell is being run, which should default to either cmd.exe or %COMSPEC% as per here: https://github.com/pyinvoke/invoke/blob/master/invoke/config.py#L447-L448

That's then handed straight into a subprocess.Popen object.

What's weird is this ought to be about the same as what fab 1's local() did. Seems maybe the only diff would be that version said Popen(..., executable=None) whereas ours will always have some non None value there. Not sure exactly what Windows does in that case; I was told by users that an explicit cmd.exe was an upgrade in behavior.

You could try testing this by explicitly configuring (via the config system - not keyword args as a None value there implies "not set" 😐) shell to be None (or just temporarily tweak your Invoke install). Might provide a clue.

Otherwise, you'd need to dig into exactly how Windows populates its PATH variable in case it leads to something else that can be done at the time we call Popen.