Is there a pipefail equivalent for dash?
8
votes
2
answers
1213
views
I have a perl script that runs a
system()
call to execute shell commands and I would like to run more than one command and pipe data between them. Something like (in perl):
system("command1 | command2");
Perl's system()
uses /bin/sh
and since these are running on an Ubuntu Server system, /bin/sh
is dash
. Like many other shells, the exit value of a pipeline in dash is the exit value of the right-most command. This means that something like this will return 0
(success):
system("false | true")
If I were on a system whose /bin/sh
were bash
, I could fix it easily by adding the pipefail
option:
system("set -o pipefail; false | true");
Indeed, this works as expected on my local Arch system whose /bin/sh
points to bash
:
$ perl -le '$status = system("false | true"); print $status>>8'
0
$ perl -le '$status = system("set -o pipefail; false | true"); print $status>>8'
1
(Yes, I know this looks weird, but if you don't know Perl, just take my word for it: we need to shift by 8 to get the actual exit status)
However, since the machine it is supposed to run on has dash
, the same thing fails:
$ perl -le '$status = system("set -o pipefail; false | true"); print $status>>8'
sh: 1: set: Illegal option -o pipefail
2
Using set -e
is also not a solution:
$ perl -le '$status = system("set -e; false | true"); print $status>>8'
0
I can think of some Perl workarounds, such as not piping or using the IPC::System::Simple
module, but I was hoping there might be a simpler way to do this directly in dash.
So, is there some trick, hack or option that lets me tell dash
that the exit status of a set of piped commands should only be 0
(success) if _all_ commands worked and should be non-0 if any of them failed the way that set -o pipefail
works in bash
?
Asked by terdon
(251605 rep)
Jul 21, 2022, 05:30 PM
Last activity: Feb 15, 2023, 12:17 PM
Last activity: Feb 15, 2023, 12:17 PM