Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

equivalent of pipefail in dash shell

Is there some similar option in dash shell corresponding to pipefail in bash?

Or any other way of getting a non-zero status if one of the commands in pipe fail (but not exiting on it which set -e would).

To make it clearer, here is an example of what I want to achieve:

In a sample debugging makefile, my rule looks like this:

set -o pipefail; gcc -Wall $$f.c -o $$f 2>&1 | tee err; if [ $$? -ne 0 ]; then vim -o $$f.c err; ./$$f; fi; 

Basically it runs opens the error file and source file on error and runs the programs when there is no error. Saves me some typing. Above snippet works well on bash but my newer Ubunty system uses dash which doesn't seem to support pipefail option.

I basically want a FAILURE status if the first part of the below group of commands fail:

gcc -Wall $$f.c -o $$f 2>&1 | tee err 

so that I can use that for the if statement.

Are there any alternate ways of achieving it?

Thanks!

like image 823
Lavya Avatar asked Jul 19 '13 23:07

Lavya


People also ask

What is Pipefail in shell?

pipefail. If set, the return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands in the pipeline exit successfully. This option is disabled by default.

What does set Pipefail do?

set -o pipefail causes a pipeline (for example, curl -s https://sipb.mit.edu/ | grep foo ) to produce a failure return code if any command errors. Normally, pipelines only return a failure if the last command errors. In combination with set -e , this will make your script exit if any command in a pipeline errors.

What is dash in shell script?

Dash (Debian Almquist shell) is a modern POSIX-compliant implementation of /bin/sh (sh, Bourne shell). Dash is not Bash compatible, but Bash tries to be mostly compatible with POSIX, and thus Dash. Dash shines in: Speed of execution. Roughly 4x times faster than Bash and others.

What is dash S in Bash?

From man bash : -s If the -s option is present, or if no arguments remain after option processing, then commands are read from the standard input. This option allows the positional parameters to be set when invoking an interactive shell.

What does the pipefail option do in PowerShell?

In this case, it sets the pipefail option. If set, causes the pipeline to return the exit status of the last (rightmost) command to exit with a non-zero status. It returns zero if all commands in the pipeline exit successfully.

Is there a way to pipefail in dash?

However, dash doesn't have the pipefail option, which is why you're getting the error.

What are the Linux set and pipefail commands?

The Linux set and pipefail commands dictate what happens when a failure occurs in a Bash script. There’s more to think about than should it stop or should it carry on. Sorry, the video player failed to load. (Error Code: 100013) Bash shell scripts are great. They’re quick to write and they don’t need compiling.

What is pipefail in Ansible and how to use it?

If you’re using the shell module with Ansible and piping the output to another command, it might be a good idea to set pipefail. This way, if the first command fails, the whole task will fail. For example, let’s say we’re running this silly task to look for /tmp directory and then trim the string “ tmp ” from the result.


2 Answers

I ran into this same issue and the bash options of set -o pipefail and ${PIPESTATUS[0]} both failed in the dash shell (/bin/sh) on the docker image I'm using. I'd rather not modify the image or install another package, but the good news is that using a named pipe worked perfectly for me =)

mkfifo named_pipe tee err < named_pipe & gcc -Wall $$f.c -o $$f > named_pipe 2>&1 echo $? 

See this answer for where I found the info: https://stackoverflow.com/a/1221844/431296

like image 137
Stan Kurdziel Avatar answered Sep 17 '22 06:09

Stan Kurdziel


The Q.'s sample problem requires:

I basically want a FAILURE status if the first part of the ... group of commands fail:

Install moreutils, and try the mispipe util, which returns the exit status of the first command in a pipe:

sudo apt install moreutils 

Then:

if mispipe "gcc -Wall $$f.c -o $$f 2>&1" "tee err" ; then \      ./$$f  else       vim -o $$f.c err  fi 

While 'mispipe' does the job here, it is not an exact duplicate of the bash shell's pipefail; from man mispipe:

   Note that some shells, notably bash, do offer a    pipefail option, however, that option does not    behave the same since it makes a failure of any    command in the pipeline be returned, not just the    exit status of the first. 
like image 27
agc Avatar answered Sep 17 '22 06:09

agc