In zsh
echo 'a string' > test.txt
echo $?
0
and
[[ $(echo 'a string') ]]
echo $?
0
whereas
[[ $(echo 'a string' > test.txt) ]]
echo $?
1
another example
curl -so 'curl-8.2.1.tar.gz' https://curl.se/download/curl-8.2.1.tar.gz
echo $?
0
or
[[ $(curl -so 'curl-8.2.1.tar.gz' https://curl.se/download/curl-8.2.1.tar.gz) ]]
echo $?
1
My questions:
- Is this because of output redirection? If no, what is causing this?
- The commands get executed successfully:
a string
appears intest.txt
and curl downloads the file to the output file I specified, why does the evaluation result infalse
? - Is there a sane way to handle this in scripting? Let's say I want to execute some command if the previous one executed successfully (but returned
false
still), how should one go about it? I could add a second check to see if the line appeared or the file was downloaded, but then the evualation of successful command execution wouldn't be necessary in the first place.
Some more examples for completeness (readability vs. "correctness"?):
if ( $(echo 'a string' > text.txt) ); then echo yes; else echo no;fi
yes
if (( $(echo 'a string' > text.txt) )); then echo yes; else echo no;fi
no
if $(echo 'a string' > text.txt); then echo yes; else echo no;fi
yes
if echo 'a string' > text.txt; then echo yes; else echo no;fi
yes
zsh
documentation: For compatibility, if there is a single argument that is not syntactically significant, typically a variable, the condition is treated as a test for whether the expression expands as a string of non-zero length. In other words, [[ $var ]] is the same as [[ -n $var ]]. It is recommended that the second, explicit, form be used where possible.