[英]Print executed command for Python subprocess.Popen
我有一个脚本可以让作者在许多 git 存储库上自动重写。
def filter_history(old, new, name, repoPath):
command = """--env-filter '
an="$GIT_AUTHOR_NAME"
am="$GIT_AUTHOR_EMAIL"
cn="$GIT_COMMITTER_NAME"
cm="$GIT_COMMITTER_EMAIL"
if [[ "$GIT_COMMITTER_NAME" = "|old|" ]]
then
cn="|name|"
cm="|new|"
fi
if [[ "$GIT_AUTHOR_NAME" = "|old|" ]]
then
an="|name|"
am="|new|"
fi
export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"
export GIT_COMMITTER_NAME="$cn"
export GIT_COMMITTER_EMAIL="$cm"
'
"""
#DO string replace
command = command.replace("|old|", old)
command = command.replace("|new|", new)
command = command.replace("|name|", name)
print "git filter-branch -f " + command
process = subprocess.Popen(['git filter-branch -f', command],cwd=os.path.dirname(repoPath), shell=True)
process.wait()
该命令执行良好,但告诉我 repo 历史记录中没有任何变化。 但是,如果我将打印出的命令(应该是正在执行的命令)放入 shell 脚本中并执行它,它会很好地更改历史记录。 我认为该命令在某种程度上没有正确执行。 有什么办法可以确切地看到子进程模块正在执行什么命令?
当您使用shell = True
, subprocess.Popen
期望将字符串作为其第一个参数。 如果可以帮助,最好不要使用shell = True
,因为它可能会带来安全风险(请参阅Warning) 。
当省略shell = True
或使用shell = False
, subprocess.Popen
需要一个参数列表。 您可以使用shlex.split
从字符串生成该参数列表:
import shlex
import subprocess
def filter_history(old, new, name, repoPath):
"""Change author info
"""
# http://help.github.com/change-author-info/
# http://stackoverflow.com/a/3880493/190597
command = """git filter-branch -f --env-filter '
an="$GIT_AUTHOR_NAME"
am="$GIT_AUTHOR_EMAIL"
cn="$GIT_COMMITTER_NAME"
cm="$GIT_COMMITTER_EMAIL"
if [[ "$GIT_COMMITTER_NAME" = "{old}" ]]
then
cn="{name}"
cm="{new}"
fi
if [[ "$GIT_AUTHOR_NAME" = "{old}" ]]
then
an="{name}"
am="{new}"
fi
export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"
export GIT_COMMITTER_NAME="$cn"
export GIT_COMMITTER_EMAIL="$cm"
'
""".format(old = old, new = new, name = name)
process = subprocess.Popen(
shlex.split(command),
cwd = os.path.dirname(repoPath))
process.communicate()
如果您的应用程序在 Windows 环境中运行,如下面的回答所述, subprocess 有一个未公开的函数subprocess.list2cmdline
,您可以使用它。 subprocess.list2cmdline
使用与 MS C 运行时相同的规则将参数序列转换为命令行字符串。
如果您使用的是 Python > 3.3,您还可以使用.args
直接从子.args
对象获取 args 列表:
import subprocess
process = subprocess.Popen(...)
subprocess.list2cmdline(process.args)
从 Python 3.8 开始,也可以使用shlex.join()
函数:
请记住,尽管该子进程通过 IPC 完成所有操作,因此最好的方法是简单地检查args
列表,因为它们将在被调用程序中传递给argv
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.