Skip to content

.tip

· one of the small things

subprocess.run takes a list, not a shell string

A command assembled as one string needs shell=True, and then a branch name with a space or a semicolon in it becomes someone else's command. Pass a list instead: it goes to execve directly, with no shell to parse it.

r = subprocess.run(["git", "log", "-1", "--format=%H", ref],
                   check=True, capture_output=True, text=True)
print(r.stdout.strip())

Without check=True a failed command returns quietly and the code carries on with an empty stdout. text=True gives str back instead of bytes.

pythonsecurity