Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I need to execute a number of piped shell commands from a non-BASH script (namely PHP script) like these:

command1 | command2 | command3

so that, if command1 fails with a non-zero exit code, each other command fails too. So far, what I've come up with is:

set -o pipefail && command1 | command2 | command3

But even though it runs fine from the terminal, it produces this if executed from the script:

sh: 1: set: Illegal option -o pipefail

share|improve this question

migrated from stackoverflow.com Nov 24 '12 at 18:12

This question came from our site for professional and enthusiast programmers.

    
It appears that /bin/sh doesn't like set -o pipefail. Is it actually bash in disguise, or is it a different shell? When bash is run as /bin/sh, does it accept set -o pipefail? –  Jonathan Leffler Nov 24 '12 at 17:24
    
@JonathanLeffler When I run /bin/sh set -o pipefail it says /bin/sh: 0: Can't open set (same thing with sudo). Hope I tested it right. The system is Ubuntu 12. –  Desmond Hume Nov 24 '12 at 17:36
    
You'd need to try /bin/sh -c "set -o pipefail"; as it was, the shell was trying to execute a script in the current directory called set and it didn't find it. –  Jonathan Leffler Nov 24 '12 at 19:29
    
@JonathanLeffler /bin/sh -c "set -o pipefail" isn't working, however bash -c "set -o pipefail" does. –  Desmond Hume Nov 24 '12 at 19:46
    
So, your problem is that the script is run by /bin/sh which doesn't recognize set -o pipefail. Consequently, you'll need to ensure that the script is run by /bin/bash instead of /bin/sh. Or, if you're confident, brave — and probably foolhardy — change /bin/sh to be a link to, or copy of, /bin/bash instead of whichever shell it currently is linked to or a copy of. If you're sure that /bin/sh is bash, then you're using behaviour which bash doesn't expose when run as /bin/sh; use bash as bash. –  Jonathan Leffler Nov 24 '12 at 19:50

2 Answers 2

up vote 3 down vote accepted

From the Bash command line you would need to invoke a subshell to avoid pipefail being set afterwards:

$ (set -o pipefail && command1 | command2 | command3)

This would limit the effect of the pipefail option to the subshell create by the parentheses (...).

A real example:

$ (set -o pipefail && false | true) && echo pipefail inactive || echo pipefail active
pipefail active

If you use an explicit shell call with the -c option you do not need a subshell, either with bash or with an sh alias to bash:

$ bash -c "set -o pipefail && false | true" && echo pipefail inactive || echo pipefail active
pipefail active
$ sh -c "set -o pipefail && false | true" && echo pipefail inactive || echo pipefail active
pipefail active

Since your sh does not accept the pipefail option, I would have to assume that it is either some older or modified version of bash - or that it is actually some other shell completely.

share|improve this answer
1  
Is $ in the first piece a part of the command is it just a shell prompt? Tried both ways, didn't really work. The bash -c way always works, not too elegant tho.. –  Desmond Hume Nov 24 '12 at 19:36

You can use $(command1) combined with $? :

a=$(echo "a")
[ $? -eq 0 ] && b=$(echo $a"b")
[ $? -eq 0 ] && c=$(echo $b"c")
echo $c

Prints "abc"

a=$(ls unexitingDir)
[ $? -eq 0 ] && b=$(echo $a"b")
[ $? -eq 0 ] && c=$(echo $b"c")
echo $c

Prints "".

"[ $? -eq 0 ] &&" means that the following command is executed only if the previous one succed.

That dosen't answer your question but it's a solution to your problem.

share|improve this answer
    
Does it mean that I would always need to store the output of each of the commands into a variable? –  Desmond Hume Nov 24 '12 at 15:44
    
Always I don't know but with my solution yes you will (if you need it for your next command). Unless you can just write command1 && command2 && command3 –  Christian Glacet Nov 24 '12 at 18:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.