Bash: One-liner to exit with the opposite status of a grep command?

后端 未结 11 2075
渐次进展
渐次进展 2021-02-06 22:08

How can I reduce the following bash script?

grep -P \"STATUS: (?!Perfect)\" recess.txt && exit 1
exit 0

It seems like I should be able

相关标签:
11条回答
  • 2021-02-06 22:28

    if anyone gets here looking for a bash return code manipulation:

    (grep <search> <files> || exit 0 && exit 123;)
    

    this will return 0 (success) when grep finds nothing, and return 123 (failure) when it does. The parenthesis are in case anyone test it as is on the shell prompt. with parenthesis it will not logout on the exit, but just exit the subshell with the same error code.

    i use it for a quick syntax check on js files:

    find src/js/ -name \*js -exec node \{\} \; 2>&1 | grep -B 5 SyntaxError || exit 0 && exit 1;
    
    0 讨论(0)
  • 2021-02-06 22:32

    I came across this, needing an onlyif statement for Puppet. As such, Tgr's bash solution wouldn't work, and I didn't want to expand the complexity as in Christopher Neylan's answer.

    I ended up using a version inspired by Henri Schomäcker's answer, but notably simplified:

    grep -P "STATUS: (?!Perfect)" recess.txt; test $? -eq 1
    

    Which very simply inverts the exit code, returning success only if the text is not found:

    • If grep returns 0 (match found), test 0 -eq 1 will return 1.
    • If grep returns 1 (no match found), test 1 -eq 1 will return 0.
    • If grep returns 2 (error), test 2 -eq 1 will return 1.

    Which is exactly what I wanted: return 0 if no match is found, and 1 otherwise.

    0 讨论(0)
  • 2021-02-06 22:34

    Use the special ? variable:

    grep -P "STATUS: (?!Perfect)" recess.txt
    exit $((1-$?))
    

    (But note that grep may also return 2, so it's not clear what you'd want to occur in such cases.)

    0 讨论(0)
  • 2021-02-06 22:35

    Just negating the return value doesn't work in a set -e context. But you can do:

    ! grep -P "STATUS: (?!Perfect)" recess.txt || false
    
    0 讨论(0)
  • 2021-02-06 22:35

    I also needed such a solution for writing puppet only if statements and came up with the following command:

    /bin/grep --quiet 'root: root@ourmasterdomain.de' /etc/aliases; if [ $? -eq 0 ]; then test 1 -eq 2; else test 1 -eq 1; fi;

    0 讨论(0)
  • 2021-02-06 22:37

    To make it work with set -e surround it in a sub-shell with ( and ):

    $ cat test.sh 
    #!/bin/bash
    
    set -ex
    (! ls /tmp/dne)
    echo Success
    $ ./test.sh 
    + ls /tmp/dne
    ls: cannot access /tmp/dne: No such file or directory
    + echo Success
    Success
    $ mkdir /tmp/dne
    $ ./test.sh 
    + ls /tmp/dne
    $ 
    
    0 讨论(0)
提交回复
热议问题