簡體   English   中英

如何將我的 shell 掃描腳本嵌入到 Python 腳本中?

[英]How do I embed my shell scanning-script into a Python script?

我一直在使用以下 shell 命令從名為scanner_name的掃描儀讀取圖像並將其保存在名為file_name的文件中

scanimage -d <scanner_name> --resolution=300 --format=tiff --mode=Color 2>&1 > <file_name>

這對我的目的來說效果很好。 我現在正在嘗試將其嵌入到 python 腳本中。 我需要像以前一樣將掃描的圖像保存到文件中,並將任何 std output (比如錯誤消息)捕獲到字符串中

我試過了

    scan_result = os.system('scanimage -d {} --resolution=300 --format=tiff --mode=Color 2>&1 > {} '.format(scanner, file_name))

但是當我在一個循環中運行它(使用不同的掃描儀)時,掃描之間存在不合理的長時間延遲,並且直到下一次掃描開始時才保存圖像(文件被創建為空文件並且直到下一次才被填充掃描命令)。 所有這些都使用scan_result=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)

但這以某種不可讀的文件格式保存了圖像

關於可能出了什么問題的任何想法? 或者我還能嘗試什么來讓我既保存文件又檢查成功狀態?

os.system() subprocess.run()比 os.system() 更受歡迎,但它們都不支持並行運行多個作業。 您將需要使用 Python 的multiprocessing庫之類的東西來並行運行多個任務(或者在基本的subprocess.Popen() API 之上痛苦地自己重新實現它)。

您對如何運行subprocess.run()也有一個基本的誤解。 您可以傳入一個字符串和shell=True或一個令牌列表和shell=False (或者根本沒有shell關鍵字; False是默認值)。

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)

您會注意到后者不支持重定向(因為這是 shell 功能),但這在 Python 中相當容易實現。 (我去掉了標准錯誤的重定向——你真的希望錯誤消息保留在 stderr 上!)

如果你有一個更大的工作 Python 程序,這應該不是很難與multiprocessing.Pool()集成。 如果這是一個小型獨立程序,我建議您完全剝離 Python 層和 go 與xargs或 GNU parallel運行限制數量的並行子進程。

我懷疑問題是您正在打開 output 文件,然后在其中運行 subprocess.run subprocess.run() 這是沒有必要的。 最終結果是,您通過 Python 打開文件,然后讓命令再次通過操作系統打開文件,然后通過 Python 關閉文件。

只需運行子進程,然后讓scanimage 2>&1> filename命令創建文件(就像直接在命令行運行scanimage一樣。)

我認為 subprocess.check_output subprocess.check_output()現在是捕獲 output 的首選方法。

IE

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)

但是,(使用runcheck_outputshell=True是一個很大的安全風險......特別是如果input_params從外部進入 Python 腳本。 人們可以傳入不需要的命令,並讓它們以腳本的權限在 shell 中運行。

有時, shell=True是操作系統命令正常運行所必需的,在這種情況下,最好的建議是使用實際的 Python 模塊與掃描儀接口 - 而不是讓 Python 將操作系統命令傳遞給操作系統。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM