Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > alt.comp.lang.shell.unix.bourne-bash > #215

Re: Trouble with PIPESTATUS

From Stephane Chazelas <stephane.chazelas@gmail.com>
Newsgroups alt.comp.lang.shell.unix.bourne-bash
Subject Re: Trouble with PIPESTATUS
Date 2015-11-02 21:16 +0000
Organization A noiseless patient Spider
Message-ID <20151102211615.GA8521@chaz.gmail.com> (permalink)
References <e0c9e002-beae-4f89-8577-4e8f45f2ea94@googlegroups.com>

Show all headers | View raw


2015-11-02 10:38:12 -0800, lynto28@gmail.com:
> Greetings,
> 
> I'm having trouble getting the PIPESTATUS with the following code:
> 
> set -o pipefail
> declare -a DIRLIST
> DIRLST=$(ls -lda /tmp/foo/* | grep ^d | awk '{print $9}')
> echo "0: ${PIPESTATUS[0]} 1: ${PIPESTATUS[1]} 2: ${PIPESTATUS[2]}"
> # 
> if [ ${PIPESTATUS[0]} -eq 0 ] && [ ${PIPESTATUS[1]} -eq 0 ] && [ ${PIPESTATUS[2]} -eq "0" ]; then
> 	echo "Direcotry List Good."
> else
> 	echo "Directory List Bad"
> fi
> 
> Only PIPESATUS[0] is getting set. Any ideas what I'm doing wrong here?
[...]

Yes PIPESTATUS doesn't work with $(...) and it's the same with
the equivalent $pipestatus in zsh. The reason is from
implementation.

In

a=$(foo | bar)

A sub-shell is created to run that pipeline, and all the
information the parent shell gets is the exit status of that
subshell which it gets by doing a waitpid() on the subshell
process. The subshell does get the exit status of each command
in the pipeline but has no way to send it back to the parent.

In order to be able to do that, the shell would have to set up
some inter-process communication channel between parent and
subshell and a protocol to send that information. But it doesn't
do it.

Not much you can do about it.

In this case though, you could test for DIRLST being the empty
string. As if it was empty, that would mean at least grep would
have failed. And if any of those command fails, the output would
typically be empty.

Note that

DIRLST=$(ls -lda /tmp/foo/* | grep ^d | awk '{print $9}')

is wrong in the general case as it assumes filenames and user
and group names don't contain  blanks or newlines.

With zsh, you'd do:

dirlst=(/tmp/foo/*(N/))

-- 
Stephane

Back to alt.comp.lang.shell.unix.bourne-bash | Previous | Next — Previous in thread | Find similar | Unroll thread


Thread

Trouble with PIPESTATUS lynto28@gmail.com - 2015-11-02 10:38 -0800
  Re: Trouble with PIPESTATUS Stephane Chazelas <stephane.chazelas@gmail.com> - 2015-11-02 21:16 +0000

csiph-web