簡體   English   中英

plumbum.commands.processes.ProcessExecutionError:對於返回 null 的命令

[英]plumbum.commands.processes.ProcessExecutionError: for commands which return null

我想運行的 shell 命令,它什么都不返回:

echo helloWorld | grep 'dummy'

鉛版:

以下線路工作:

out=(echo["helloWorld"] | grep["h"])().strip()

但以下行沒有,可能是什么原因?

out=(echo["helloWorld"] | grep["dummy"])().strip()
print(out)

我遇到的錯誤:

Traceback (most recent call last):
  File "dd.py", line 6, in <module>
    out=(echo["helloWorld"] | grep["dummy"])().strip()
  File "/home/user/venv/lib/python3.5/site-packages/plumbum/commands/base.py", line 103, in __call__
    return self.run(args, **kwargs)[1]
  File "/home/user/venv/lib/python3.5/site-packages/plumbum/commands/base.py", line 240, in run
    return p.run()
  File "/home/user/venv/lib/python3.5/site-packages/plumbum/commands/base.py", line 201, in runner
    return run_proc(p, retcode, timeout)
  File "/home/user/venv/lib/python3.5/site-packages/plumbum/commands/processes.py", line 232, in run_proc
    return _check_process(proc, retcode, timeout, stdout, stderr)
  File "/home/user/venv/lib/python3.5/site-packages/plumbum/commands/processes.py", line 23, in _check_process
    proc.verify(retcode, timeout, stdout, stderr)
  File "/home/user/venv/lib/python3.5/site-packages/plumbum/commands/base.py", line 412, in verify
    dstproc_verify(retcode, timeout, stdout, stderr)
  File "/home/user/venv/lib/python3.5/site-packages/plumbum/machines/base.py", line 26, in verify
    stderr)
plumbum.commands.processes.ProcessExecutionError: Command line: ['/bin/grep', 'dummy']
Exit code: 1

[Q]我該如何解決這個錯誤?

發生這種情況是因為 grep 的退出狀態是 1 如果它沒有找到任何東西, 如其手冊中所述

如果您願意,可以在命令行中嘗試:

echo helloWorld | grep h; echo $?
echo helloWorld | grep x; echo $?

會導致

helloWorld
0
1

避免這種情況的方法在另一個不錯的答案中進行了描述,例如

echo helloWorld | grep x | cat

將產生 0 作為狀態。 但不幸的是,plumbum 做了一個本地管道機制,所以 grep 輸出到 plumbum,然后 plumbum 將它管道到下一個命令——這意味着貓不能吞下退出代碼 1,在它之前會拋出一個異常。

所以我的兩個想法是創建一個 shell 腳本來運行 grep 從不返回沒有結果的搜索錯誤:

#!/bin/bash
grep "$@" || test $? = 1

並執行它而不是 grep(在原始答案中稱為 c1grep),或者在管道代碼周圍添加一個 try/except 塊並手動處理退出代碼 1 (ProcessExecutionError)。

另一個答案是正確的,但不是最優的 - 該問題可以在 plumbum 中解決,不需要包裝grep的外部腳本,也不必捕獲異常。

這個想法是使用 plumbum 的run方法來做兩件事:

  • 強制鉛垂接受來自被調用程序的任何退出代碼(默認情況下,如果返回的錯誤代碼不為零,則會引發異常)。
  • 捕獲包含錯誤代碼、標准輸出和被調用程序的標准錯誤的元組,而不是像通常那樣只包含標准輸出。

工作示例:

for s in ["hello","dummy"]:
    exitcode,stdout,stderr = (echo["helloWorld"] | grep[s]).run (retcode=None)

    if exitcode == 0:
        print (stdout.strip())

    if exitcode != 0:
        print (f"string {s} not present")
        print (stderr)

前面的代碼返回:

helloWorld
string dummy not present

沒有提出任何異常。

暫無
暫無

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

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