【问题标题】:plumbum.commands.processes.ProcessExecutionError: for commands which return nullplumbum.commands.processes.ProcessExecutionError:对于返回 null 的命令
【发布时间】:2018-09-01 14:13:02
【问题描述】:

我要运行的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]我该如何解决这个错误?

【问题讨论】:

    标签: python plumbum


    【解决方案1】:

    发生这种情况是因为如果 grep 没有找到任何内容,则退出状态为 1,如 its manual 中所述

    如果您愿意,可以在命令行中尝试:

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

    会导致

    helloWorld
    0
    1
    

    避免这种情况的方法在另一个 nice answer 中进行了描述,例如

    echo helloWorld | grep x | cat
    

    将产生 0 作为状态。但不幸的是,plumbum 做了一个本地管道机制,所以 grep 输出到 plumbum,然后 plumbum 将它通过管道传递给下一个命令——这意味着猫不能吞下退出代码 1,它之前会抛出一个异常。

    所以我的两个想法是要么创建一个 shell 脚本来运行一个 grep,在没有结果的情况下搜索时永远不会返回错误:

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

    并执行此命令而不是 grep(在原始答案中称为 c1grep),或者在管道代码周围添加一个 try/except 块并手动处理退出代码 1 (ProcessExecutionError)。

    【讨论】:

      【解决方案2】:

      另一个答案是正确的,但不是最优的 - 问题可以直接解决,无需包装 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
      
      

      不引发任何异常。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-14
        • 2019-09-10
        • 1970-01-01
        • 1970-01-01
        • 2014-05-23
        • 2017-04-13
        相关资源
        最近更新 更多