[clug] Next in my series of "how to do things in /bin/sh that you probably shouldn't".

Kevin Pulo kev at pulo.com.au
Wed Aug 19 21:43:22 MDT 2009


On Thu, Aug 20, 2009 at 12:44:42PM +1000, Andrew Janke wrote:

> > And you have to pick an environment variable that won't
> > clash (unless you want to muck around using eval to set an envvar
> > based on $$ (in the parent) and $PPID (in the child)).
> 
> erky!  Surely the name of the script plus a bit of glook would work in
> 99.9% of cases.

Not if you plan on having multiple copies of the script running at any
given time.  People sometimes rely on $$ when generating temp files,
which can be dicey because pids are only unique for the lifetime of
the process.

> >    #!/bin/bash
> >    if [ "x$redir" = "x" ]; then
> >        redir=y "$0" "$@" 2>&1 | tee ${0##*/}.log
> >        exit $?
> >    else
> >        unset redir
> >    fi
> 
> Nice! Still I am not entirely sure why you need the else as "$redir"
> should be local to the call inside the if? Or am I missing something?

The "call" is forking another process.  $redir is used for the parent
process to communicate to the re-exec'd child that the redirection has
been done.  So if you don't unset redir, things will still work, but
$redir will hang around and "pollute" the environment space.  ie:

    #! /bin/sh
    if [ "x$redir" = "x" ]; then
        redir=y "$0" "$@" 2>&1 | tee fred.log
        exit $?
    fi
    echo "$redir"

will output "y".

To put it another way, these lines are equivalent:

    redir=y "$0" "$@" 2>&1 | tee fred.log

and

    export redir=y
    "$0" "$@" 2>&1 | tee fred.log
    unset redir

That is, doing "foo=bar somecommand" has the effect of setting $foo,
but only for the environment of the "somecommand" process.

ash can unset variables, so I'm not sure what the problem there is.
Dunno about /bin/sh on OSX.

The full (and portable) thing isn't THAT ugly.  ;)

    #! /bin/sh
    n="_`basename "$0" | sed -e 's/[^A-Za-z0-9_]/_/g'`"
    eval "redir=\"\$${n}_${PPID}_redir\""
    if test "x$redir" = "x"; then
        eval "${n}_$$_redir=y ; export ${n}_$$_redir"
        "$0" "$@" 2>&1 | tee logfile.log
        exit $?
    else
        unset n redir "${n}_${PPID}_redir"
    fi

Kev

-- 
.----------------------------------------------------------------------.
| Kevin Pulo                Quidquid latine dictum sit, altum viditur. |
| kev at pulo.com.au               _ll l_ng__g_e_ _r_ hi__ly p__d_ct__le. |
| http://www.kev.pulo.com.au/         God casts the die, not the dice. |
`--------------- Linux: The choice of a GNU generation. ---------------'
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.samba.org/pipermail/linux/attachments/20090820/f132a4e1/attachment.pgp>


More information about the linux mailing list