为什么用Python脚本调用这个外部程序会出错?
我正在尝试从Python调用Martchus的 tageditor,虽然在命令行窗口中可以正常使用该命令,但从Python调用时总是会报错。
import os
import subprocess
# Specify the export path and file format
export_path = "C:\\Users\\lords\\Videos\\MCOC Videos\\"
#file_prefix = project.GetName()
file_prefix = "Untitled Project 2"
file_format = "jpg"
filepath = os.path.join(export_path, file_prefix + "." + file_format)
cmd = [
"tageditor-cli",
f'set cover="{filepath}"',
f'-f "{os.path.join(export_path, file_prefix)}.mp4"'
]
#cmd = f"tageditor-cli set cover=\"{filepath}\" -f \"{os.path.join(export_path, file_prefix)}.mp4\""
try:
result = subprocess.run(
cmd,
capture_output=True,
timeout=10,
check=True
)
print(result.stdout)
except subprocess.TimeoutExpired:
print("The command timed out.")
except subprocess.CalledProcessError as e:
print(f"Command failed with exit code {e.returncode} {e.stderr}")
运行时会得到如下结果:
['tageditor-cli', "set cover'=C:\\Users\\lords\\Videos\\MCOC Videos\\Untitled Project 2.jpg'", '-f %C:\\Users\\lords\\Videos\\MCOC Videos\\Untitled Project 2.mp4%']
Command failed with exit code 1 b'Error: Unable to parse arguments: The argument "file" mustn\'t be specified more than 1 time.\r\nSee --help for available commands.\r\n'
我可以通过使用那个第二个命令赋值来让它工作,但我不知道为什么数组版本不起作用。
在看了一个类似的帖子之后,我也试了这个:
cmd = [
"tageditor-cli",
'set',
'cover=',
str('"' + shlex.quote(filepath) + '"'),
'-f',
str(shlex.quote(export_path + file_prefix + ".mp4"))
]
解决方案
list2cmdline 只会在元素包含空格或制表符时才会加引号。所以你的三个列表元素大致会被拼接成:
tageditor-cli "set cover=\"C:\Users\lords...\Untitled Project 2.jpg\"" "-f \"C:\Users...\Untitled Project 2.mp4\""
tageditor的参数解析器将 -f视为一个标志,会把后面的定位值作为文件来处理。它也会把那个第一个拼接在一起的参数中的裸路径视为另一个定位文件(因为解析后它看起来像一个路径)。这就是错误的来源。
每个CLI令牌必须是它自己的列表元素。不要把 set cover=... 拼成一个字符串,也不要把 -f "path" 拼成一个字符串,也不要手动加引号:
import os
import subprocess
export_path = r"C:\Users\lords\Videos\MCOC Videos"
file_prefix = "Untitled Project 2"
cover_path = os.path.join(export_path, f"{file_prefix}.jpg")
video_path = os.path.join(export_path, f"{file_prefix}.mp4")
cmd = [
"tageditor-cli",
"set",
f"cover={cover_path}", # no quotes — subprocess handles spaces
"-f",
video_path, # no quotes
]
try:
result = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=10,
check=True,
)
print(result.stdout)
except subprocess.TimeoutExpired:
print("The command timed out.")
except subprocess.CalledProcessError as e:
print(f"Command failed with exit code {e.returncode}: {e.stderr}")
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。