Shell script termination with exit function in backquotes
Devin Teske
dteske at vicor.com
Sat Mar 19 16:45:01 UTC 2011
On Mar 19, 2011, at 9:15 AM, Maxim Khitrov wrote:
> On Mon, Mar 14, 2011 at 6:40 PM, Andres Perera <andres.p at zoho.com> wrote:
>> On Mon, Mar 14, 2011 at 7:46 AM, Maxim Khitrov <max at mxcrypt.com> wrote:
>>> On Mon, Mar 14, 2011 at 3:16 AM, Andres Perera <andres.p at zoho.com> wrote:
>>>> On Sun, Mar 13, 2011 at 9:49 PM, Devin Teske <dteske at vicor.com> wrote:
>>>>> If you make the changes that I've suggested, you'll have consistent execution. The reason you're having inconsistent behavior is because Linux has /bin/sh symbolically linked to /bin/bash while FreeBSD has a more traditional shell (we'll call it bourne shell "plus").
>>>>
>>>> that is misleading because command substitutions have traditionally
>>>> invoked subshells, and freebsd sh(1)/ash is an exception, not the norm
>>>>
>>>> in this case, ksh and bash deviates are clearly closer to standard
>>>> bourne behaviour
>>>>
>>>
>>> Thanks for that explanation. I can understand the benefits of
>>> optimizing away subshell execution, but that can clearly lead to
>>> unexpected behavior. Is there some documentation on when this
>>> optimization is utilized (i.e. the command executed without a
>>> subshell)? Would I be correct in assuming that it is only restricted
>>> to built-in commands that are known not to produce any output, such as
>>> 'exit'?
>>
>> i would check the source, autoconf docs, and http://www.in-ulm.de/~mascheck/
>>
>> netbsd has been patched to fix `exit 1`, according to the last site
>
> Here's another, but related, problem that I just ran into. The man page reads:
>
> Commands may be grouped by writing either
> (list)
> or
> { list; }
> The first form executes the commands in a subshell. Note that built-in
> commands thus executed do not affect the current shell...
>
> Here's my script:
>
> ----
> #!/bin/sh
>
> { A=1; }; echo $A
> echo | { B=2; }; echo $B
> { C=3; } > /dev/null; echo $C
> ----
>
> And here's the output:
>
> ----
> 1
>
> 3
> ----
>
> Where did the '2' go?
You're learning that there are deviations to the rule as-mentioned in the man-page.
At least two variations to the rule that { ... } is a block of commands executed in the current shell are:
1. When the block appears as a function and
2. When the block appears on the right-hand side of a pipe (with or without following pipe(s)).
The reason for these deviations is quite simple in-fact...
The shell needs to create a new set of stdin/stdout file-descriptors for the block of commands that you've created, and executing said commands within a sub-shell achieves that.
I hope that helps explain.
--
Devin
> Again, I have to assume that when stdin is piped
> to a group of commands, those commands are executed in a subshell
> despite curly braces. But where is this behavior documented? It seems
> that there are a lot of corner cases that can only be understood if
> you are familiar with the shell implementation. Documentation can
> certainly be improved in places.
>
> - Max
More information about the freebsd-questions
mailing list