且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

发送STDERR /标准输出信息的功能,并捕获退出信号

更新时间:2023-02-22 14:36:36

您必须使用

 设置-o pipefail

请参阅此related ***的问题。


小例子

 #!/斌/庆典陷阱处理程序ERR
处理程序(){回声被困; }回音1
假| :回音2
设置-o pipefail
假| :

输出

  $的bash test.sh
1
2
被困

Im working on error handling and logging in my bash script. Below I have included a simplified code snippet that exemplify the use case.

I want to achieve following in my script:

  1. trap exit signals which should trigger onexit() function in the code below
  2. stderr and stdout should be sent to the log() function which will make sure to log the output to an log file according to specific log format (simplified in the example below)

Issue with current code below:

  • Step 1 is not trapped by onexit function and script is continuing to Step 2. Most probably because stderr is piped to logStd(). How can I send error messages to logStd() but still trap the exit signal in onexit()?

Resolution:

  1. Add set -o pipefail
  2. Get exit status on onexit() by adding local exit_status=${1:-$?}

script.sh (edited after resolution)

#!/bin/bash -E
set -o pipefail

# Perform program exit housekeeping
function onexit {
    local exit_status=${1:-$?}
    log "onexit() called with param: $exit_status"
    exit $1
}

# Simplified log function that sends input parameter to echo. This function is used within this script
# In real case this function would send log statement to log file according to specific log format
function log {
    echo "log(): $1"
}

# Simplified log function that reads input stream and sends to log
# This function is used from commands
function logStd {
    log "logStd() called"
    while IFS= read -r line; do log "$line"; done
}

# http://linuxcommand.org/wss0160.php
# The trap command allows you to execute a command when a signal is received by your script.
# Usage: trap arg signals
# "signals" is a list of signals to intercept and "arg" is a command to execute when one of the signals is received
# arg can either be a command or a function name like clean_up below
trap onexit 1 2 3 15 ERR

# STEP 1 - should fail, send errors to logstd() and be trapped by onexit()
log "**Tarballing should fail, file doesn´t exist"
tar -czf /Users/ismar.slomic/shellscripting/unknownfile.txt.gz /Users/ismar.slomic/shellscripting/unknownfile.txt 2>&1 | logStd

# STEP 2 - should run successfully and send "tar: Removing leading '/' from member names" to logStd()
log "**Tarballing should run successfully"
tar -czf /Users/ismar.slomic/shellscripting/file.txt.gz /Users/ismar.slomic/shellscripting/file.txt 2>&1 | logStd

onexit

output:

log(): **Tarballing should fail, file doesn´t exist
log(): logStd() called
log(): tar: /Users/ismar.slomic/shellscripting/unknownfile.txt: Cannot stat:  No such file or directory
log(): tar: Error exit delayed from previous errors.
log(): **Tarballing should run successfully
log(): logStd() called
log(): tar: Removing leading '/' from member names
log(): onexit() called with param:

You have to use

set -o pipefail

See this related *** Question.


Minimal example:

#!/bin/bash

trap handler ERR
handler() { echo trapped ; }

echo 1
false | :

echo 2
set -o pipefail
false | :

Output:

$ bash test.sh
1
2
trapped