Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Honoring a command



    Hi Bart :)

 * Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> dixit:
> }     verbosely_do "Doing whatever command" whatever.command \
> }         || { print "Message" >&2; return 1;}
> If you have access to the "initscripts" package, you might take a look
> at /etc/rc.d/init.d/functions -- particularly the "action" function
> that is defined in that file.  It does pretty much exactly what your
> "verbosely_do" is meant to do (with the addition of wrapping the call
> in something called "initlog" which makes syslog entries for the
> command, but you can take that out).

    I don't have that package (well, I've took a look at the
initscripts package for Debian, but I think you were talking about
the RPM one)

> I'd also note that both "action" and "verbosely_do" are assuming that
> whatever.command does not produce any standard output of its own, or
> else that it's been redirected away somewhere (which is part of what
> "initlog" does, I think).

    Yes, in all my shell functions the command does not spit anything
through stdout (or has it redirected as well). That's the reason of
the '2>' in my examples: I really don't care about stdout because it
is handled, but stderr is not.
 
> Given that the command itself produces no output, you might consider
> something like this:

    Bart, you're a genius :)) This solution is simpler, more
powerful and flexible since it doesn't pass the command as a
parameter, shorter, easier to understand, does not mess a lot with
AND lists or OR lists, etc... The number of beers I owe you is
growing dangerously ;)
 
>     verbosely_watch() {
>         emulate -L zsh
>         local output
>         print -u2 -n ${(r:WIDTH:)1}
>         if read output
>         then
>             print -u2 $output
>         else
>             print -u2 '[ok]'
>         fi
>     }
> 
>     TRAPZERR() { print '[fail]' }
>     { whatever.command } 2>/dev/null | verbosely_watch "Doing whatever"

    I'm going to change it a bit, for not using TRAPZERR: I use it
for other purpose in my scripts, although that doesn't seem to work
:( (see below)

    verbosely_watch() {
        emulate -L zsh
        local output
        print -u2 -n ${(r:WIDTH:)1}
        if read output
        then
            print -u2 '[fail]'
            print $output
        else
            print -u2 '[ok]'
        fi
    }

    And after that, I'm going to use it as:

    { whatever.command 2> /dev/null || print "Error message"} \
        | verbosely_watch "Doing whatever"

    I have the following alias, called 'scriptinit', which is called
in all my scripts:

    alias scriptinit=$'emulate -L zsh ; trap \'return $LINENO\' ZERR'

    That way, anytime a script fails, its return code tells me the
line the failure took place, and I can have silent scripts for some
tasks, which still give information about what caused the error (if
any). The problem is that it doesn't work with the above usage of
verbosely_watch, because the trap is never run due to the OR list. I
must replace:

    { whatever.command 2> /dev/null || print "Error message"}

    by:

    { whatever.command 2> /dev/null || print "Error message";false}

    for my generic trap to work :(, but then 'verbosely_watch' has no
purpose at all! I think I'd better use 'scriptinit' only for muted
scripts and verbosely_watch for the rest, using TRAPZERR for the
error message. Is that a good idea?

    Thanks a lot Bart, as always.

    Raúl Núñez de Arenas Coronado

-- 
Linux Registered User 88736
http://www.pleyades.net & http://raul.pleyades.net/



Messages sorted by: Reverse Date, Date, Thread, Author