如何将shell扫描脚本嵌入到Python脚本中?
我们一直在使用下面的shell命令从名为scanner\u name的扫描仪读取图像,并将其保存在名为file\u name的文件中如何将shell扫描脚本嵌入到Python脚本中?,python,shell,scanning,Python,Shell,Scanning,我们一直在使用下面的shell命令从名为scanner\u name的扫描仪读取图像,并将其保存在名为file\u name的文件中 scanimage -d <scanner_name> --resolution=300 --format=tiff --mode=Color 2>&1 > <file_name> 但是,当我在一个循环中运行它(使用不同的扫描仪)时,扫描之间存在不合理的长时间延迟,并且图像在下一次扫描开始之前不会保存(该文件被创建为空
scanimage -d <scanner_name> --resolution=300 --format=tiff --mode=Color 2>&1 > <file_name>
但是,当我在一个循环中运行它(使用不同的扫描仪)时,扫描之间存在不合理的长时间延迟,并且图像在下一次扫描开始之前不会保存(该文件被创建为空文件,并且在下一次扫描命令之前不会填充)。所有这些,扫描结果=0,即指示无错误
已经向我建议了子流程方法run(),我已经尝试过了
with open(file_name, 'w') as scanfile:
input_params = '-d {} --resolution=300 --format=tiff --mode=Color 2>&1 > {} '.format(scanner, file_name)
scan_result = subprocess.run(["scanimage", input_params], stdout=scanfile, shell=True)
但这以某种无法读取的文件格式保存了图像
对可能出现的问题有什么想法吗?或者我还可以尝试什么方法来保存文件并检查成功状态?我怀疑问题在于您正在打开输出文件,然后在其中运行
子进程.run()
。这是没有必要的。最终的结果是,您通过Python打开文件,然后让命令通过操作系统再次打开文件,然后通过Python关闭文件
只需运行子流程,并让scanimage 2>&1>文件名
命令创建文件(就像直接在命令行运行scanimage
一样)
我认为子流程。check_output()
现在是捕获输出的首选方法
即
但是,run
和check\u output
)的shell=True
是一个很大的安全风险。。。尤其是当输入参数
从外部进入Python脚本时。人们可以传入不需要的命令,并让它们在具有脚本权限的shell中运行
有时,OS命令需要shell=True
才能正常运行,在这种情况下,最好的建议是使用实际的Python模块与扫描器接口,而不是让Python将OS命令传递给OS subprocess.run()
肯定比os.system()
更受欢迎,但它们都不支持并行运行多个作业。您需要使用类似Python库的工具来并行运行多个任务(或者在basicsubprocess.Popen()
API上自己痛苦地重新实现)
对于如何运行子流程。run()
,您还有一个基本的误解。您可以传入字符串和shell=True
或令牌列表和shell=False
(或者根本没有shell
关键字;False
是默认值)
您会注意到后者不支持重定向(因为这是一个shell特性),但这在Python中相当容易实现。(我删除了标准错误的重定向--您真的希望错误消息保留在stderr上!)
如果您有一个更大的工作Python程序,那么与
多处理.Pool()
集成应该不会太难。如果这是一个小型的独立程序,我建议您完全剥离Python层,使用类似于xargs
或GNUparallel
的方法来运行有限数量的并行子进程。您不能使用subprocess.run([…list…],shell=True)
,它可以通过shell=True
传递一个单一的sting,也可以通过没有shell的令牌列表。如果传递令牌列表和shell=False
,则不能使用诸如重定向之类的shell功能。有关更多详细信息,请参阅我对线程化表示怀疑,但有一些提示。是比较老的(所以可能需要加一点盐),但更接近我的建议。
with open(file_name, 'w') as scanfile:
input_params = '-d {} --resolution=300 --format=tiff --mode=Color 2>&1 > {} '.format(scanner, file_name)
scan_result = subprocess.run(["scanimage", input_params], stdout=scanfile, shell=True)
from subprocess import check_output
# Command must be a list, with all parameters as separate list items
command = ['scanimage',
'-d{}'.format(scanner),
'--resolution=300',
'--format=tiff',
'--mode=Color',
'2>&1>{}'.format(file_name)]
scan_result = check_output(command)
print(scan_result)
with_shell = subprocess.run(
"scanimage -d {} --resolution=300 --format=tiff --mode=Color 2>&1 > {} ".format(
scanner, file_name), shell=True)
with open(file_name) as write_handle:
no_shell = subprocess.run([
"scanimage", "-d", scanner, "--resolution=300", "--format=tiff",
"--mode=Color"], stdout=write_handle)