Awk 当它被回响时,我们会对状态进行检查,如果没有找到,则处理当前行,而不是延迟一行。 function close_and_get_exit_status(cmd) { # magic goes here... } BEGIN { cmd =

Awk 当它被回响时,我们会对状态进行检查,如果没有找到,则处理当前行,而不是延迟一行。 function close_and_get_exit_status(cmd) { # magic goes here... } BEGIN { cmd = ,awk,posix,getline,Awk,Posix,Getline,当它被回响时,我们会对状态进行检查,如果没有找到,则处理当前行,而不是延迟一行。 function close_and_get_exit_status(cmd) { # magic goes here... } BEGIN { cmd = "echo foo; echo bar; echo baz; false" while ((cmd | getline line) > 0) print "got a line of text: " line

当它被回响时,我们会对状态进行检查,如果没有找到,则处理当前行,而不是延迟一行。
function close_and_get_exit_status(cmd) {
    # magic goes here...
}
BEGIN {
    cmd = "echo foo; echo bar; echo baz; false"
    while ((cmd | getline line) > 0)
        print "got a line of text: " line
    if (close_and_get_exit_status(cmd) != 0) {
        print "ERROR: command '" cmd "' failed" | "cat >&2"
        exit 1
    }
    print "command '" cmd "' was successful"
}
$ awk -f foo.awk
got a line of text: foo
got a line of text: bar
got a line of text: baz
ERROR: command 'echo foo; echo bar; echo baz; false' failed
$ echo $?
1
"command || echo failure" | getline var; ... if( var == "failure" ) exit;
function stderr(msg) { print msg | "cat >&2"; }
function error(msg) { stderr("ERROR: " msg); }
function fatal(msg) { error(msg); exit 1; }

# Wrap cmd so that each output line of cmd is prefixed with "d".
# After cmd is done, an additional line of the format "r<ret>" is
# printed where "<ret>" is the integer return code/exit status of the
# command.
function safe_cmd_getline_wrap(cmd) {
    return                                                  \
        "exec 3>&1;"                                        \
        "ret=$("                                            \
        "    exec 4>&1;"                                    \
        "    { ( "cmd" ) 4>&-; echo $? >&4; } 3>&- |"       \
        "    awk '{print\"d\"$0;fflush()}' >&3 4>&-;"       \
        ");"                                                \
        "exec 3>&-;"                                        \
        "echo r${ret};"
}

# like "cmd | getline line" except:
#   * if getline fails, the awk script exits with an error
#   * if cmd fails (returns non-zero), the awk script exits with an
#     error
#   * safe_cmd_getline_close(cmd) must be used instead of close(cmd)
function safe_cmd_getline(cmd,        wrapped_cmd,ret,type) {
    wrapped_cmd = safe_cmd_getline_wrap(cmd)
    ret = (wrapped_cmd | getline line)
    if (ret == -1) fatal("failed to read line from command: " cmd)
    if (ret == 0) return 0
    type = substr(line, 1, 1)
    line = substr(line, 2)
    if (type == "d") return 1
    if (line != "0") fatal("command '" cmd "' failed")
    return 0
}
function safe_cmd_getline_close(cmd) {
    if (close(safe_cmd_getline_wrap(cmd))) fatal("failed to close " cmd)
}
cmd = "ls no-such-file"
while (safe_cmd_getline(cmd)) {
    print "got a line of text: " line
}
safe_cmd_getline_close(cmd)
$ cat tst.awk    
BEGIN {
    cmd = "echo foo; echo bar; echo baz; false"

    mod = cmd "; echo \"$?\""
    while ((mod | getline line) > 0) {
        if (numLines++)
            print "got a line of text: " prev
        prev = line
    }
    status = line
    close(mod)

    if (status != 0) {
        print "ERROR: command '" cmd "' failed" | "cat >&2"
        exit 1
    }
    print "command '" cmd "' was successful"
}

$ awk -f tst.awk
got a line of text: foo
got a line of text: bar
got a line of text: baz
ERROR: command 'echo foo; echo bar; echo baz; false' failed
$ echo $?
1
#!/bin/sh
set -e
file=$(mktemp)
finish() {
    rm -f "$file"
}
trap 'finish' EXIT
trap 'finish; trap - INT; kill -s INT $$' INT
trap 'finish; trap - TERM; kill $$' TERM

awk -v file="$file" 'BEGIN{
    o_cmd="echo foo; echo bar; echo baz; false"
    cmd = "("o_cmd "); echo $? >\""file"\""
    print cmd
    while ((cmd | getline) > 0) {
        print "got a line of text: " $0
    }
    close(cmd)
    getline ecode <file; close(file)
    print "exit status:", ecode
    if(ecode)exit 1
}'