1

I'm trying to figure out how to handle a bash logical operator ('&&') in a Python subprocess.

The command, obviously works as expected on the terminal:

git fetch && git diff --name-only ..origin/master

When I try this, I get an error saying C is an unknown switch:

subprocess.Popen(['git', '-C', repo_path, 'fetch', '&&', 'git', '-C', repo_path, 'diff', '--name-only', '..origin/master'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

I'm sure I am missing something silly, but I can't find anything regarding how to handle the '&&' operator.

Thanks for your help

Edit

Thanks @heitor for pointing in the good direction.

Basically, Popen doesn't use shell operator by default, shell=True need to be added.

I'm still getting an git error, which might be related to the -C option. I'll work on this error tomorrow. Cheers.

fantomH
  • 15
  • 4
  • The answers on that page vary in how helpful they are, so to summarise - you would need to add `shell=True`, and for the command you use a string rather than a list of strings. `subprocess.Popen("git fetch && git diff --name-only ..origin/master", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)` – alani Jul 09 '20 at 02:12
  • Or use `communicate()` then check `.returncode` https://stackoverflow.com/questions/5631624/how-to-get-exit-code-when-using-python-subprocess-communicate-method –  Jul 09 '20 at 02:16
  • The main point here is the need for `shell=True`. And when that is used, you need the command as a string. The linked page seems to suggest that you would still use a list for the command arguments, which I am led to believe would work under Windows but is not portable. – alani Jul 09 '20 at 02:18
  • 1
    Although @user - what you are saying makes sense _if_ you clarify that it involves two separate `Popen` invocations. – alani Jul 09 '20 at 02:20

1 Answers1

0

This should do what you're after, assuming you're above python 3.5!

r = subprocess.run("git fetch && git diff --name-only ..origin/master", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(r.stdout)
print(r.stderr)

I noticed that you'd added -C and prepended repo_path into your subprocess command, but these don't seem to fit the format of the original shell commands you were intending on using? Apologies if I've misinterpreted this, but I believe the above is what you're after based on the original shell commands and it solves your && issue...

Good luck!

JimCircadian
  • 171
  • 7