-   Linux - Newbie (
-   -   Using shell command output as input in shell script - how to do? (

EnderX 06-30-2010 12:08 PM

Using shell command output as input in shell script - how to do?
If what I am asking for is something that should have been obvious, I apologize.

I have been requested to build a script for starting and stopping our main (postgresql) database's slony replication system, said script intended to be run at boot. I've got a shell script working in a sort of skeletal fashion (it does what it's supposed to under the assumption that nothing can go wrong), but I'm wondering about how to set it to catch errors.

The code itself calls a set of shell commands I was given to manually start and stop the replication. The catch is, in the past I have sometimes seen a 'failed to start' message in the output from those, even though it otherwise appeared to have successfully run. My habit is, after seeing this message, to immediately kill replication and attempt to restart it again. Given that the script for this is supposed to be a 'run at boot' task, I need some way to programatically do this.

My actual question is this: How do I have my script look over the output a prior command inside it generated? I'm fairly sure I can just run the stop and start procedures as '$0 stop, $0 start' if needed, but how do I isolate that 'failed' message and return it for code use? I'm assuming grep to isolate, but beyond that I'm in the dark. Even if all you care to offer is the name of the command or commands I need, I will be grateful.

Additionally, if there are any other flaws to my logic, I would greatly appreciate having them pointed out to me before I manage to accidentally mangle the system I'm building this for, and request that you please do so.

Thank you for your consideration.

Didier Spaier 06-30-2010 12:19 PM

It's hard to figure out what you could do not seeing your script as it is.

Could you post it, surrounded by CODE tags to make it easier to read ?

catkin 06-30-2010 12:46 PM

You could start by looking at actual boot scripts. Mostly they do little error trapping, they simply allow output from the commands they run to go to console where they are visible (assuming no boot splash or effective boot logging). It's helpful if they print a (terse) message saying what they intend to do; this allows a possibly mysterious error message to be rapidly traced to a particular script.

Your ideas of the script analysing the output from commands is more appropriate for a script which is not sending output to console. It's great for rapid troubleshooting of scripts that output to log where more-or-less sophisticated functions to handle messaging/logging can be useful, especially in the develop/test/debug cycle when a script may be run from the command prompt and saves having to consult the log if messages are automatically sent to the controlling terminal when there is one or otherwise to log.

Command output can (almost always) be captured by

cmd_out=$( <some command> 2>&1 )
after which $? is set to <some command>'s return code and can conveniently saved for later reference with rc=$?.

Now you've got the available data from running the command, what you do with it depends on the command and context -- which outputs and return codes do you want to treat as information, warning or error (or whatever other classification you choose)? In simple cases any non-zero return code is a fatal error so you could use something like

cmd_out=$( <some command> 2>&1 )
if [[ $rc ]]; then
    echo "Error while <doing something>.  Return code $rc.  Command output:"$(\n)"$cmd_out" >&2
    exit 1 

In more complex cases you might need to parse the output

cmd_out=$( <some command> 2>&1 )
case "$cmd_out" in
    <OK expression 1> | <OK expression 2> | ... | <OK expression n> )
        <do nothing unless you want to log informational message>
    <WARNING expression 1> | ... | <WARNING expression n> )
        <log warning message>
    <ERROR expression 1> | ... | <ERROR expression n> )
        <log error message and call finalise function or exit>
    * )
        <log unhandled error message and call finalise function or exit>

It may be useful to include the name of the script -- ${0##*/} -- or the line number -- $LINENO -- in messages.

All times are GMT -5. The time now is 05:03 PM.