Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将shell扫描脚本嵌入到Python脚本中?_Python_Shell_Scanning - Fatal编程技术网

如何将shell扫描脚本嵌入到Python脚本中?

如何将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> 但是,当我在一个循环中运行它(使用不同的扫描仪)时,扫描之间存在不合理的长时间延迟,并且图像在下一次扫描开始之前不会保存(该文件被创建为空

我们一直在使用下面的shell命令从名为scanner\u name的扫描仪读取图像,并将其保存在名为file\u 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库的工具来并行运行多个任务(或者在basic
subprocess.Popen()
API上自己痛苦地重新实现)

对于如何运行
子流程。run()
,您还有一个基本的误解。您可以传入字符串和
shell=True
或令牌列表和
shell=False
(或者根本没有
shell
关键字;
False
是默认值)

您会注意到后者不支持重定向(因为这是一个shell特性),但这在Python中相当容易实现。(我删除了标准错误的重定向--您真的希望错误消息保留在stderr上!)


如果您有一个更大的工作Python程序,那么与
多处理.Pool()
集成应该不会太难。如果这是一个小型的独立程序,我建议您完全剥离Python层,使用类似于
xargs
或GNU
parallel
的方法来运行有限数量的并行子进程。

您不能使用
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)