编辑跳到答案:问题是我插入的字符串中有一个肉眼看不见的非ascii字符。
我正在尝试运行这个ImageMagick命令:
convert -verbose -size 732x142 xc:transparent -fill black -stroke black -strokewidth 2 -draw "roundrectangle 0,0 732,142 18,18" "Sample Card Title.png"
如果我直接从命令行运行它,它会正常运行。
只是我试图在Python脚本中运行它,其中大多数值是由脚本生成的。当我从那里启动它时,使用相同的值,ImageMagick错误,报告:
convert: non-conforming drawing primitive definition `roundrectangle' @ error/draw.c/RenderMVGContent/4506.
rectangle_coordinates = f""roundrectangle 0,0 {mm_to_px(62)},{mm_to_px(box_height)} {mm_to_px(1.5)},{mm_to_px(1.5)}""
command = f"convert -verbose -size {dimensions} xc:transparent -fill black -stroke black -strokewidth 2 -draw {rectangle_coordinates} "{filename}""
print(command)
os.system(command)
如果我删除变量"rectangle_coordinates"并将其替换为硬代码,然后它就可以工作了:
command = f"convert -size {dimensions} xc:transparent -fill black -stroke black -strokewidth 2 -draw "roundrectangle 0,0 732,142 18,18" "{filename}""
print(command)
os.system(command)
如果我将打印(命令)行的结果从输出复制粘贴到提示符中并运行它,它就会正常运行。但是当用os运行时。系统,它正在调用的命令错误。
有人看到为什么这个命令会失败的一个部分插值,但运行良好,当它是硬编码?
注:是的,我知道subprocess.run()比os.system()更可取。在调试期间,我已经尝试了这个命令的许多变体,对于我尝试的每个不同的事情,将参数分成一个列表只是增加了一个(人为)错误源。我回到了os。在我寻找漏洞的时候。一旦我解决了这个bug,我将很高兴回到subprocess.run()。
运行脚本调用作为…
subprocess.run(["convert", "-size", dimensions, "xc:transparent", "-fill", "black", "-stroke", "black", "-strokewidth", "2", "-draw", rectangle_coordinates, ""{resisted_consequence_filename}""])
…产生与操作系统相同(或更多)的错误。系统版本。
P.P.S.是的,我也知道Python有多个ImageMagick包装器。我不喜欢添加额外的抽象层,尤其是在寻找bug的时候。
在subprocess.call()
参数中,您不应该在最后一个参数中添加字面引号。在shell中,只有在将多个单词组合成一个单词时才需要引号,但这已经通过使它们成为单独的列表元素来实现了。
subprocess.run(["convert", "-size", dimensions, "xc:transparent", "-fill", "black", "-stroke", "black", "-strokewidth", "2", "-draw", rectangle_coordinates, resisted_consequence_filename])
我找到了答案。我不得不离开几天再回来。
事实上,你不能在Stack Overflow上看到它,原因和我很难找到它的原因是一样的:
在插入问题变量之前,我的代码在问题变量的定义中有一个不可中断的空格。
也就是在这一行:
rectangle_coordinates = f""roundrectangle 0,0 {mm_to_px(62)},{mm_to_px(box_height)} {mm_to_px(1.5)},{mm_to_px(1.5)}""
最后一个空格不是正常的空格,ascii码0x20。它是一个unicode不间断空格,码点C2A0。
你在Stack Overflow上看不到这个bug,因为和打印到终端一样,当我复制粘贴到这里时,它也被转换为标准空间。如果我真的将我在这里发布的示例代码反向复制到我的原始代码中,它将覆盖错误。
10 Headdesk
20 Goto 10
我终于在绝望中发现了这个错误,我想,"如果我把命令写到一个文件,然后从一个文件中读回来会怎么样?当然,这将消化字符串插值,迫使它解析行,就像我硬编码它一样。当我第一次硬编码一个示例文本文件时,当然是可行的。但是当我让程序写入文本文件并读取它时,它又失败了。但是现在我有了硬编码的版本和程序编写的版本,肉眼看起来是一样的,但又不一样。所以我用十六进制编辑器打开了它们,结果是:一个字符不同,尽管它们在屏幕上打印的是一样的。