Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.unix.shell > #4871 > unrolled thread
| Started by | kj <no.email@please.post> |
|---|---|
| First post | 2012-05-01 21:20 +0000 |
| Last post | 2012-05-03 18:20 +0000 |
| Articles | 11 — 4 participants |
Back to article view | Back to comp.unix.shell
[zsh] How to mimic errexit within subshell (or function)? kj <no.email@please.post> - 2012-05-01 21:20 +0000
Re: [zsh] How to mimic errexit within subshell (or function)? Stephane Chazelas <stephane.chazelas@gmail.com> - 2012-05-02 07:34 +0100
Re: [zsh] How to mimic errexit within subshell (or function)? Geoff Clare <geoff@clare.See-My-Signature.invalid> - 2012-05-02 13:51 +0100
Re: [zsh] How to mimic errexit within subshell (or function)? Stephane Chazelas <stephane.chazelas@gmail.com> - 2012-05-02 14:29 +0100
Re: [zsh] How to mimic errexit within subshell (or function)? kj <no.email@please.post> - 2012-05-02 19:33 +0000
Re: [zsh] How to mimic errexit within subshell (or function)? Stephane Chazelas <stephane.chazelas@gmail.com> - 2012-05-02 20:53 +0100
Re: [zsh] How to mimic errexit within subshell (or function)? Martin Vaeth <vaeth@mathematik.uni-wuerzburg.de> - 2012-05-02 10:30 +0000
Re: [zsh] How to mimic errexit within subshell (or function)? kj <no.email@please.post> - 2012-05-02 19:09 +0000
Re: [zsh] How to mimic errexit within subshell (or function)? kj <no.email@please.post> - 2012-05-02 19:12 +0000
Re: [zsh] How to mimic errexit within subshell (or function)? Stephane Chazelas <stephane.chazelas@gmail.com> - 2012-05-02 20:27 +0100
Re: [zsh] How to mimic errexit within subshell (or function)? kj <no.email@please.post> - 2012-05-03 18:20 +0000
| From | kj <no.email@please.post> |
|---|---|
| Date | 2012-05-01 21:20 +0000 |
| Subject | [zsh] How to mimic errexit within subshell (or function)? |
| Message-ID | <jnpk36$jqs$1@reader1.panix.com> |
The following scheme doesn't work as expected: despite the set -e
(errexit), the subshell does not exit on error (it just goes on to
execute the next command):
#!/usr/bin/zsh
(
set -e
cmd0...
cmd1...
cmd2...
...
echo "$0: done"
) || { echo "$0: failed" && exit 1 }
How can I mimic the behavior of "set -e" within a subshell? (Or
within a function, for that matter?) (I realize that I can always
append "|| exit 1" to every command, but this is precisely what
I'd like to avoid.)
Thanks!
~kj
[toc] | [next] | [standalone]
| From | Stephane Chazelas <stephane.chazelas@gmail.com> |
|---|---|
| Date | 2012-05-02 07:34 +0100 |
| Message-ID | <20120502063438.GA10446@chaz.gmail.com> |
| In reply to | #4871 |
2012-05-01 21:20:38 +0000, kj:
>
>
> The following scheme doesn't work as expected: despite the set -e
> (errexit), the subshell does not exit on error (it just goes on to
> execute the next command):
>
> #!/usr/bin/zsh
> (
> set -e
> cmd0...
> cmd1...
> cmd2...
> ...
> echo "$0: done"
> ) || { echo "$0: failed" && exit 1 }
>
> How can I mimic the behavior of "set -e" within a subshell? (Or
> within a function, for that matter?) (I realize that I can always
> append "|| exit 1" to every command, but this is precisely what
> I'd like to avoid.)
[...]
Try
zsh -ec '
cmd1
cmd2...
' || ...
Or:
(
setopt nodebugbeforecmd
TRAPDEBUG() { ((!$?)) || exit; }
cmd1
cmd2...
) || ...
I personally wouldn't touch "set -e" with a barge pole, and
would use some « || die '...' »
With die() being a function that takes an optional argument to
display on stderr and exits with a non-zero exit status.
--
Stephane
[toc] | [prev] | [next] | [standalone]
| From | Geoff Clare <geoff@clare.See-My-Signature.invalid> |
|---|---|
| Date | 2012-05-02 13:51 +0100 |
| Message-ID | <f8n779-hk5.ln1@leafnode-msgid.gclare.org.uk> |
| In reply to | #4872 |
Stephane Chazelas wrote:
> 2012-05-01 21:20:38 +0000, kj:
>>
>> The following scheme doesn't work as expected: despite the set -e
>> (errexit), the subshell does not exit on error (it just goes on to
>> execute the next command):
>>
>> #!/usr/bin/zsh
>> (
>> set -e
>> cmd0...
>> cmd1...
>> cmd2...
>> ...
>> echo "$0: done"
>> ) || { echo "$0: failed" && exit 1 }
> Try
>
> zsh -ec '
> cmd1
> cmd2...
> ' || ...
Or try
(
set -e
cmd1
cmd2...
)
test $? -eq 0 || ...
(I don't have zsh, but that works in ksh, bash and dash).
--
Geoff Clare <netnews@gclare.org.uk>
[toc] | [prev] | [next] | [standalone]
| From | Stephane Chazelas <stephane.chazelas@gmail.com> |
|---|---|
| Date | 2012-05-02 14:29 +0100 |
| Message-ID | <20120502132926.GF10446@chaz.gmail.com> |
| In reply to | #4874 |
2012-05-02 13:51:59 +0100, Geoff Clare:
> Stephane Chazelas wrote:
>
> > 2012-05-01 21:20:38 +0000, kj:
> >>
> >> The following scheme doesn't work as expected: despite the set -e
> >> (errexit), the subshell does not exit on error (it just goes on to
> >> execute the next command):
> >>
> >> #!/usr/bin/zsh
> >> (
> >> set -e
> >> cmd0...
> >> cmd1...
> >> cmd2...
> >> ...
> >> echo "$0: done"
> >> ) || { echo "$0: failed" && exit 1 }
>
> > Try
> >
> > zsh -ec '
> > cmd1
> > cmd2...
> > ' || ...
>
> Or try
>
> (
> set -e
> cmd1
> cmd2...
> )
> test $? -eq 0 || ...
>
> (I don't have zsh, but that works in ksh, bash and dash).
[...]
Indeed, though I had assumed "set -e" was also in effect in the
rest of the script (and "|| ..." was so that the failure of the
subshell wouldn't exit the script)
In that case, you can temporarily disable "set -e"
...
set +e
(
set -e
cmd1
cmd2...
)
rc=$?
set -e
[ "$rc" -eq 0 ] || ...
--
Stephane
[toc] | [prev] | [next] | [standalone]
| From | kj <no.email@please.post> |
|---|---|
| Date | 2012-05-02 19:33 +0000 |
| Message-ID | <jns26e$h77$1@reader1.panix.com> |
| In reply to | #4872 |
In <20120502063438.GA10446@chaz.gmail.com> Stephane Chazelas <stephane.chazelas@gmail.com> writes:
>Try
>zsh -ec '
> cmd1
> cmd2...
>' || ...
>Or:
>(
> setopt nodebugbeforecmd
> TRAPDEBUG() { ((!$?)) || exit; }
> cmd1
> cmd2...
>) || ...
Thanks!
>I personally wouldn't touch "set -e" with a barge pole,
*gulp*, that's really bad news, since I have 'set -e' all over my
scripts...
I just searched for "set -e" bugs for zsh online, and found only
a couple of (sufficiently distinct-looking) hits:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=520101
http://permalink.gmane.org/gmane.linux.debian.devel.bugs.general/545456
Is this what you have in mind?
~k
[toc] | [prev] | [next] | [standalone]
| From | Stephane Chazelas <stephane.chazelas@gmail.com> |
|---|---|
| Date | 2012-05-02 20:53 +0100 |
| Message-ID | <20120502195328.GH10446@chaz.gmail.com> |
| In reply to | #4883 |
2012-05-02 19:33:34 +0000, kj: [...] > >I personally wouldn't touch "set -e" with a barge pole, > > > *gulp*, that's really bad news, since I have 'set -e' all over my > scripts... > > I just searched for "set -e" bugs for zsh online, and found only > a couple of (sufficiently distinct-looking) hits: > > http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=520101 > http://permalink.gmane.org/gmane.linux.debian.devel.bugs.general/545456 > > Is this what you have in mind? [...] No, that's about coding practice, maintainability and reliability. Relying on "set -e" to do your error handling is a bad idea in anything more than the simplest of scripts that just run a command after the other. - commands can have non-zero exit statuses that don't mean an error (see "test", "expr", "grep"...) - subtleties like the one you discovered about where its effects are cancelled - interactions with subshells, pipes, background jobs - some commands will output errors, some will no, "set -e" will not explain why the script dies. You just can't assume it works without having to worry. And if you start to worry, it's a lot simpler to do the error handling properly. That's my opinion anyway. -- Stephane -
[toc] | [prev] | [next] | [standalone]
| From | Martin Vaeth <vaeth@mathematik.uni-wuerzburg.de> |
|---|---|
| Date | 2012-05-02 10:30 +0000 |
| Message-ID | <slrnjq235r.qt6.vaeth@lounge.imp.fu-berlin.de> |
| In reply to | #4871 |
kj <no.email@please.post> wrote: > > despite the set -e (errexit), the subshell does > not exit on error Here it does (in script and also interactive): # ( set -e; printf a; false; printf b ); echo $? a1
[toc] | [prev] | [next] | [standalone]
| From | kj <no.email@please.post> |
|---|---|
| Date | 2012-05-02 19:09 +0000 |
| Message-ID | <jns0pa$apr$1@reader1.panix.com> |
| In reply to | #4873 |
First of all, thanks for all the replies! In <slrnjq235r.qt6.vaeth@lounge.imp.fu-berlin.de> Martin Vaeth <vaeth@mathematik.uni-wuerzburg.de> writes: >kj <no.email@please.post> wrote: >> >> despite the set -e (errexit), the subshell does >> not exit on error >Here it does (in script and also interactive): ># ( set -e; printf a; false; printf b ); echo $? >a1 Thanks. But now I'm **really** confused. I don't why the first subshell below (i.e. your version) terminates upon error but the second one (mine) doesn't: % ( set -e; printf a; false; printf b ); echo $? a1 % ( set -e; printf a; false; printf b ) || echo $? ab% Actually, I don't understand why mine doesn't work, period, since I can't find anything in the zsh docs saying that it shouldn't... Any pointers to the place in the zsh docs where this is explained would be much appreciated. (I hope that *some day* I'll learn to find my way around the zsh documentation, but I'm nowhere near that point yet.) ~kj
[toc] | [prev] | [next] | [standalone]
| From | kj <no.email@please.post> |
|---|---|
| Date | 2012-05-02 19:12 +0000 |
| Message-ID | <jns0vn$onv$1@reader1.panix.com> |
| In reply to | #4880 |
[fixing a typo here]
In <jns0pa$apr$1@reader1.panix.com> kj <no.email@please.post> writes:
>...But now I'm **really** confused. I don't why the first
^
get
>subshell below (i.e. your version) terminates upon error but the
>second one (mine) doesn't:
>% ( set -e; printf a; false; printf b ); echo $?
>a1
>% ( set -e; printf a; false; printf b ) || echo $?
>ab%
>Actually, I don't understand why mine doesn't work, period, since
>I can't find anything in the zsh docs saying that it shouldn't...
>Any pointers to the place in the zsh docs where this is explained
>would be much appreciated. (I hope that *some day* I'll learn to
>find my way around the zsh documentation, but I'm nowhere near that
>point yet.)
>~kj
[toc] | [prev] | [next] | [standalone]
| From | Stephane Chazelas <stephane.chazelas@gmail.com> |
|---|---|
| Date | 2012-05-02 20:27 +0100 |
| Message-ID | <20120502192715.GG10446@chaz.gmail.com> |
| In reply to | #4880 |
2012-05-02 19:09:30 +0000, kj: > > First of all, thanks for all the replies! > > In <slrnjq235r.qt6.vaeth@lounge.imp.fu-berlin.de> Martin Vaeth > <vaeth@mathematik.uni-wuerzburg.de> writes: > > >kj <no.email@please.post> wrote: > >> > >> despite the set -e (errexit), the subshell does > >> not exit on error > > >Here it does (in script and also interactive): > > ># ( set -e; printf a; false; printf b ); echo $? > >a1 > > Thanks. But now I'm **really** confused. I don't why the first > subshell below (i.e. your version) terminates upon error but the > second one (mine) doesn't: > > % ( set -e; printf a; false; printf b ); echo $? > a1 > % ( set -e; printf a; false; printf b ) || echo $? > ab% > > Actually, I don't understand why mine doesn't work, period, since > I can't find anything in the zsh docs saying that it shouldn't... > Any pointers to the place in the zsh docs where this is explained > would be much appreciated. (I hope that *some day* I'll learn to > find my way around the zsh documentation, but I'm nowhere near that > point yet.) [...] It's not specific to zsh. The effect of "set -e" is cancelled when on the left hand side of || or && or in and "if", "while" or "until". Basically everywhere where the exit status is checked. In other words, when a non-zero exit status is checked as part of a condition. false exits the shell. (false fails) but not false || true (false is taken as a condition upon which to execute true or not) A side effect is that "set -e" is cancelled for the whole of the subshell in: (false; echo still here) || true It's a bit confusing but that's how all the shells behave. "|| true" or "|| : ignore errors" is the idiom to say you don't care about the exit status when "set -e" is in effect. set -e command-that-may-fail-but-we-dont-care || : ignore error -- Stephane
[toc] | [prev] | [next] | [standalone]
| From | kj <no.email@please.post> |
|---|---|
| Date | 2012-05-03 18:20 +0000 |
| Message-ID | <jnui9j$b8b$1@reader1.panix.com> |
| In reply to | #4882 |
In <20120502192715.GG10446@chaz.gmail.com> Stephane Chazelas <stephane.chazelas@gmail.com> writes: >2012-05-02 19:09:30 +0000, kj: >> >> First of all, thanks for all the replies! >> >> In <slrnjq235r.qt6.vaeth@lounge.imp.fu-berlin.de> Martin Vaeth >> <vaeth@mathematik.uni-wuerzburg.de> writes: >> >> >kj <no.email@please.post> wrote: >> >> >> >> despite the set -e (errexit), the subshell does >> >> not exit on error >> >> >Here it does (in script and also interactive): >> >> ># ( set -e; printf a; false; printf b ); echo $? >> >a1 >> >> Thanks. But now I'm **really** confused. I don't why the first >> subshell below (i.e. your version) terminates upon error but the >> second one (mine) doesn't: >> >> % ( set -e; printf a; false; printf b ); echo $? >> a1 >> % ( set -e; printf a; false; printf b ) || echo $? >> ab% >> >> Actually, I don't understand why mine doesn't work, period, since >> I can't find anything in the zsh docs saying that it shouldn't... >> Any pointers to the place in the zsh docs where this is explained >> would be much appreciated. (I hope that *some day* I'll learn to >> find my way around the zsh documentation, but I'm nowhere near that >> point yet.) >[...] >It's not specific to zsh. <helpful explanation snipped> >It's a bit confusing but that's how all the shells behave. Hmm... I wonder if this is why the zsh documentation does not mention this bit of general shell weirdness (AFAICT). Be that as it may, thanks for the clarification. In <20120502195328.GH10446@chaz.gmail.com> Stephane Chazelas <stephane.chazelas@gmail.com> writes: >2012-05-02 19:33:34 +0000, kj: >> http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=520101 >> http://permalink.gmane.org/gmane.linux.debian.devel.bugs.general/545456 >> >> Is this what you have in mind? >[...] >No, that's about coding practice, maintainability and >reliability. >Relying on "set -e" to do your error handling is a bad idea in >anything more than the simplest of scripts that just run a >command after the other. >- commands can have non-zero exit statuses that don't mean an > error (see "test", "expr", "grep"...) >- subtleties like the one you discovered about where its effects > are cancelled >- interactions with subshells, pipes, background jobs >- some commands will output errors, some will no, "set -e" will > not explain why the script dies. >You just can't assume it works without having to worry. >And if you start to worry, it's a lot simpler to do the error >handling properly. That's food for thought, thanks. Maybe it's time to revisit my approach to error handling in shell scripts... ~k
[toc] | [prev] | [standalone]
Back to top | Article view | comp.unix.shell
csiph-web