pythonplumbum

plumbum.commands.processes.ProcessExecutionError: for commands which return null


The shell command I want to run, which returns nothing:

echo helloWorld | grep 'dummy'

plumbum version:

Following line works:

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

But following line does not, what might be the reason?

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

Error I am having:

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] How could I fix this error?


Solution

  • This happens because the exit status of grep is 1 if it does not find anything, as described in its manual

    You can try it in command line if you wish:

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

    Will result in

    helloWorld
    0
    1
    

    Ways to circumvent this are described in another nice answer, e.g.

    echo helloWorld | grep x | cat
    

    will yield 0 as status. But unfortunately plumbum does a local pipe mechanism so grep output goes to plumbum, and then plumbum pipes it to the next command - meaning the cat can't swallow the exit code 1, there will be an exception thrown before it.

    So my two ideas are to either create a shell script to run a grep never returning error on search without results:

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

    and execute this instead of the grep (called c1grep in the original answer), or to add a try/except block around your pipe code and manually handle the exit code 1 (ProcessExecutionError).