Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 13 Mar 2011 19:19:14 -0700
From:      Devin Teske <dteske@vicor.com>
To:        Maxim Khitrov <max@mxcrypt.com>
Cc:        FreeBSD <freebsd-questions@freebsd.org>
Subject:   Re: Shell script termination with exit function in backquotes
Message-ID:  <759A467E-407A-4DB8-9756-08011B5405F0@vicor.com>
In-Reply-To: <AANLkTi=-CFmxRicGcosvzhBbM3DMjbWwQNirMrJ1_KP=@mail.gmail.com>
References:  <AANLkTi=-CFmxRicGcosvzhBbM3DMjbWwQNirMrJ1_KP=@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help

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

> Hello everyone,
>=20
> 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:
>=20
> ----
> #!/bin/sh
>=20
> exit_prog()
> {
> 	echo -n 'before'
> 	exit 0
> 	echo -n 'after'
> }
>=20
> 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:
> ----
>=20
> 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:
>=20
> ----
> line 1: before
> line 2:
> ----
>=20
> 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.
>=20
> 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@localhost ~ $ cat << "EOF" | /bin/sh -
> echo PS1=3D$PS1; : `unset PS1`; echo PS1=3D$PS1
> EOF
PS1=3D\[\e[32;1m\]\u@\H \[\e[34m\]\W \$\[\e[0m\]
PS1=3D

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@localhost ~ $ cat << "EOF" | /bin/sh -
> echo PS1=3D$PS1; : `(unset PS1)`; echo PS1=3D$PS1
> EOF
PS1=3D\[\e[32;1m\]\u@\H \[\e[34m\]\W \$\[\e[0m\]
PS1=3D\[\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.
>=20
> 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").


>=20
> ----
> line 1: before
> line 2:
> line 3:
> line 4:
> ----
>=20
> What's going on here?
>=20
> - Max
> _______________________________________________
> freebsd-questions@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-questions
> To unsubscribe, send any mail to =
"freebsd-questions-unsubscribe@freebsd.org"

--=20
Cheers,
Devin Teske


-> LEGAL DISCLAIMER <-
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.

-> FUN STUFF <-
-----BEGIN GEEK CODE BLOCK-----
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+++
------END GEEK CODE BLOCK------
http://www.geekcode.com/

-> END TRANSMISSION <-




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?759A467E-407A-4DB8-9756-08011B5405F0>