当我在外壳中运行git tag -l v1.1.{[0-9],[0-9][0-9]}
时,我会得到结果,但是
def run_command(cmd_args, number_of_retry=5,
timeout_in_second=90, suppress_output=False):
proc = subprocess.Popen(cmd_args,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
timer = threading.Timer(timeout_in_second, proc.kill)
timer.start()
out, err = proc.communicate()
timer.cancel()
if proc.returncode and number_of_retry >= 1:
if not suppress_output:
print('Command "{}" failed/timeout, retrying...'.format(
' '.join(cmd_args)))
return run_command(cmd_args,
number_of_retry - 1,
timeout_in_second + 10,
suppress_output=suppress_output)
return proc.returncode, out, err
return_code, out, _ = run_command(
['git', 'tag', '-l', "v1.1.{[0-9],[0-9][0-9]}"],
number_of_retry=0,
suppress_output=False)
无结果。将我的代码中的模式更改为v1.1。[0-9] [0-9]会产生匹配的结果,与v1.1。[0-9]一样,因此括号中存在问题。有人知道这怎么可能吗?还有另一种方式来表达相同的表达式,或者至少看到bash子进程正在运行,以便可以验证是否正在运行正确的命令吗? (子进程和线程是python模块)
答案 0 :(得分:2)
v1.1.{[0-9],[0-9][0-9]}
中的花括号和逗号语法(“花括号扩展”)是对shell的指令,而不是对git
的指令;它告诉外壳程序将参数拆分为两个(此后,由于它们包含未加引号的glob字符,因此外壳程序默认情况下会尝试将每个结果参数扩展为glob-希望您实际上并不打算这样做,并且因此不必介意它消失了),然后传递git
两个单独的参数,一个用于大括号内逗号两侧的内容。
缺少先前讨论的遍历,此shell扩展的结果等效于以下Python代码:
run_command(['git', 'tag', '-l', 'v1.1.[0-9]', 'v1.1.[0-9][0-9]'],
number_of_retry=0, suppress_output=False)
如果您实际上是 do 依靠外壳程序将v1.1.[0-9]
替换为当前目录中与该模式匹配的条目列表(如果存在任何此类条目,则本机Python等效项为)更像是:
# to behave like default bash behavior (without running ''shopt -s nullglob''):
import glob
def expandGlob(word):
return glob.glob(word) or [word]
run_command(['git', 'tag', '-l'] + expandGlob('v1.1.[0-9]') + expandGlob('v1.1.[0-9][0-9]'),
number_of_retry=0, suppress_output=False)