shell script ssh command exit status

后端 未结 4 910
天命终不由人
天命终不由人 2020-12-31 01:34

In a loop in shell script, I am connecting to various servers and running some commands. For example

#!/bin/bash
FILENAME=$1
cat $FILENAME | while read HOST
         


        
4条回答
  •  爱一瞬间的悲伤
    2020-12-31 02:26

    Perhaps prepare the log file on the other side and pipe it to stdout, like this:

    ssh -n user@example.com 'x() { local ret; "$@" >&2; ret=$?; echo "[`date +%Y%m%d-%H%M%S` $ret] $*"; return $ret; };
    x true
    x false
    x sh -c "exit 77";'  > local-logfile 
    

    Basically just prefix everything on the remote you want to invoke with this x wrapper. It works for conditionals, too, as it does not alter the exit code of a command.

    You can easily loop this command.

    This example writes into the log something like:

    [20141218-174611 0] true
    [20141218-174611 1] false
    [20141218-174611 77] sh -c exit 77
    

    Of course you can make it better parsable or adapt it to your whishes how the logfile shall look like. Note that the uncatched normal stdout of the remote programs is written to stderr (see the redirection in x()).

    If you need a recipe to catch and prepare output of a command for the logfile, here is a copy of such a catcher from https://gist.github.com/hilbix/c53d525f113df77e323d - but yes, this is a bit bigger boilerplate to "Run something in current context of shell, postprocessing stdout+stderr without disturbing return code":

    # Redirect lines of stdin/stdout to some other function
    # outfn and errfn get following arguments
    # "cmd args.." "one line full of output"
    : catch outfn errfn cmd args..
    catch()
    {
    local ret o1 o2 tmp
    tmp=$(mktemp "catch_XXXXXXX.tmp")
    mkfifo "$tmp.out"
    mkfifo "$tmp.err"
    pipestdinto "$1" "${*:3}" <"$tmp.out" &
    o1=$!
    pipestdinto "$2" "${*:3}" <"$tmp.err" &
    o2=$!
    "${@:3}" >"$tmp.out" 2>"$tmp.err"
    ret=$?
    rm -f "$tmp.out" "$tmp.err" "$tmp"
    wait $o1
    wait $o2
    return $ret
    }
    
    : pipestdinto cmd args..
    pipestdinto()
    {
    local x
    while read -r x; do "$@" "$x" &2
    }
    
    catch_example()
    {
    # Example use
    catch NOTE ERR find /proc -ls
    }
    

    See the second last line for an example (scroll down)

提交回复
热议问题