10

When I run

curl | tee test.txt; echo ${PIPESTATUS[0]}

I correctly see

curl: try 'curl --help' or 'curl --manual' for more information

2

But when I try to run exactly same command using '/bin/sh':

sh -c "curl | tee test.txt; echo \${PIPESTATUS[0]}"

I get

curl: try 'curl --help' or 'curl --manual' for more information

sh: 1: Bad substitution

How we can resolve Bad substitution problem, please?

4 Answers4

13

You solve it by not using sh.

The PIPESTATUS variable specifically, and the ${var[idx]} array syntax in general, are features specific to the Bash shell. They do not exist in POSIX sh, and even shells that do have arrays might use a different syntax.

It just happens that some Linux distributions symlink their /bin/sh to Bash. Other distributions, however, symlink it to dash, Debian Almquist Shell. Both are compatible with POSIX sh scripts, but only Bash accepts the ${PIPESTATUS[…]} syntax.

So if you want to use it, run bash -c "…" instead.

grawity
  • 501,077
8

Workaound for '/bin/sh' or busybox

status=0
eval ` { ls /dontexists || echo status="$?"; } | tee /dev/null`
echo "# status=${status}"

Trace :

busybox sh ~/bin/test.sh 
+ status=0
+ ls /dontexists
+ tee /dev/null
ls: /dontexists: No such file or directory
+ echo status=1
+ eval status=1
+ status=1
+ echo # status=1
# status=1
rzr
  • 314
  • 3
  • 8
1

Also 'bash -c' seems to have a problem with it when called from tcsh:

bash -c "curl | tee test.txt; echo \${PIPESTATUS[0]}"

PIPESTATUS: Undefined variable.

This works for me from tcsh:

bash -c 'curl | tee test.txt; echo ${PIPESTATUS[0]}'

curl: try 'curl --help' or 'curl --manual' for more information
2

GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)
called from tcsh 6.17.06

atmchem
  • 11
0

You probably ask this question, because you use the busybox shell that does not have the PIPESTATUS array. In that case, the only option will be to set -o pipefail. But if you are using one of the almost extinct shells that does not have PIPESTATUS or -o pipefail, then you may consider writing temporary files either for the intermediate output or the return value.