繁体   English   中英

subprocess.run 无法执行带有 var=value 前缀的 git 命令,但 os.system 没有问题

[英]subprocess.run failing to execute git command with var=value prefix but os.system does it without issue

我在这里遇到了一个奇怪的问题。

我正在尝试自动克隆一些 GitHub 存储库,但在os.system或直接在我的 shell 中运行命令的情况下,我看到subprocess.run错误,工作正常。

这是我要运行的命令:

subprocess.run('GIT_TERMINAL_PROMPT=0 git clone https://github.com/fake-user/fake-repo.git'.split())

这导致了这个错误:

>>> subprocess.run('GIT_TERMINAL_PROMPT=0 git clone https://github.com/fake-user/fake-repo.git'.split())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/omermikhailk/.pyenv/versions/3.11.0/lib/python3.11/subprocess.py", line 546, in run
    with Popen(*popenargs, **kwargs) as process:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/omermikhailk/.pyenv/versions/3.11.0/lib/python3.11/subprocess.py", line 1022, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/Users/omermikhailk/.pyenv/versions/3.11.0/lib/python3.11/subprocess.py", line 1899, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'GIT_TERMINAL_PROMPT=0'

当结果应该是os.system给出的结果时:

>>> os.system('GIT_TERMINAL_PROMPT=0 git clone https://github.com/fake-user/fake-repo.git')
Cloning into 'fake-repo'...
fatal: could not read Username for 'https://github.com': terminal prompts disabled
32768

有人会碰巧知道这背后的原因吗?

您需要改用以下内容:

subprocess.run(['git', 'clone', 'https://github.com/fake-user/fake-repo.git'], env={'GIT_TERMINAL_PROMPT': '0'})

当您通过子进程运行命令时,您没有使用bashsh或任何 shell,因此环境变量不会被解释,并且必须通过env指定,而不是 CLI。

请注意,最好自己明确地为命令及其 arguments 制作列表,而不是使用字符串和.split() 如果您有任何包含空格的 arguments,而不是在作为列表元素传递的字符串中包含文字引号,您将使用包含完整参数的字符串。 即,不是['echo', '"foo', 'bar"'] (这将是.split()的结果),而是['echo', 'foo bar']来包含空格。

关于为什么会发生这种情况的另一个注意事项是subprocess.run在技术上允许您传递shell=True ,但是如果您正在处理任何可能由用户生成的内容,则出于安全考虑,您应该不惜一切代价避免这样做。 最佳做法是按照建议使用env={...}

如果需要包含当前环境变量,则可以使用以下命令:

from os import environ

env = environ.copy()
env['GIT_TERMINAL_PROMPT'] = '0'

subprocess.run(['git', 'clone', 'https://github.com/fake-user/fake-repo.git'], env=env)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM