Shell script termination with exit function in backquotes

Devin Teske dteske at
Mon Mar 14 02:19:15 UTC 2011

On Mar 13, 2011, at 5:26 PM, Maxim Khitrov wrote:

> Hello everyone,
> I might be doing something dumb here, but this doesn't make sense to
> me. When I run the following script, I would expect to see no output:
> ----
> #!/bin/sh
> exit_prog()
> {
> 	echo -n 'before'
> 	exit 0
> 	echo -n 'after'
> }
> echo line 1: `exit_prog`
> echo line 2:
> echo line 3: `exit 1`

Replace with:

echo line 3: `( exit 1 )`

This executes the command within a sub-shell (preventing the exit call from effecting the current shell -- achieving what you desire).

> echo line 4:
> ----
> The reason I expect to see no output is because 'exit 0' should be
> called before any of the echo lines are allowed to execute. Instead,
> what I get on FreeBSD 7 & 8 is:
> ----
> line 1: before
> line 2:
> ----
> I don't understand this because 'exit 0' seems to terminate the call
> to 'exit_prog',

The function call is performed in a sub-shell (internally).

> but the execution of the script continues. However,
> when 'exit 1' is called, the script terminates before printing out the
> last 2 lines.
> It seems that 'exit' inside a function doesn't work when that function
> is called with backquotes. I assume it has something to do with the
> fact that commands in backquotes are executed in a sub-shell

That is incorrect. Here is a unit-test (to be performed on FreeBSD):

dteske at localhost ~ $ cat << "EOF" | /bin/sh -
> echo PS1=$PS1; : `unset PS1`; echo PS1=$PS1
PS1=\[\e[32;1m\]\u@\H \[\e[34m\]\W \$\[\e[0m\]

The above scriptlet does three things:

1. echo's the contents of the PS1 environment variable.
2. Executes "unset PS1" within back-ticks.
3. re-echo's the contents of the PS1 environment variable.

Upon execution, we see that despite being executed within back-ticks, the PS1 variable was wiped-out. If commands on FreeBSD under /bin/sh were executed within a sub-shell, said sub-shell would have a separate environment that wouldn't effect its parent. Contrast this behavior with the following scriptlet:

dteske at localhost ~ $ cat << "EOF" | /bin/sh -
> echo PS1=$PS1; : `(unset PS1)`; echo PS1=$PS1
PS1=\[\e[32;1m\]\u@\H \[\e[34m\]\W \$\[\e[0m\]
PS1=\[\e[32;1m\]\u@\H \[\e[34m\]\W \$\[\e[0m\]

In the above, we've re-executed the same script but with one minor change -- we've placed the "unset PS1" command within parentheses, which under FreeBSD's /bin/sh causes the creation of a sub-shell with separate environment and exit code, etc.

You can read more on FreeBSD by searching sh(1) for "Grouping Commands Together".

> , but the
> behavior is inconsistent.
> When I run the same script on RHEL using bash, all 4 lines are printed:

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").

> ----
> line 1: before
> line 2:
> line 3:
> line 4:
> ----
> What's going on here?
> - Max
> _______________________________________________
> freebsd-questions at mailing list
> To unsubscribe, send any mail to "freebsd-questions-unsubscribe at"

Devin Teske

This message  contains confidential  and proprietary  information
of the sender,  and is intended only for the person(s) to whom it
is addressed. Any use, distribution, copying or disclosure by any
other person  is strictly prohibited.  If you have  received this
message in error,  please notify  the e-mail sender  immediately,
and delete the original message without making a copy.

Version 3.12
GAT/CS/B/CC/E/IT/MC/M/MU/P/S/TW d+(++) s: a- C+++@$ UB++++$ P++++@$ L++++$ E-
W+++ N? o? K? w@ O M++$ V- PS+>++ PE@ Y+ PGP-> t(+) 5? X(+) R(-) tv+ b+>++ DI+
D+(++) G++ e>++++ h r+++ z+++


More information about the freebsd-questions mailing list