发送STDERR /标准输出信息的功能,并捕获退出信号 [英] Send stderr/stdout messages to function and trap exit signal

查看:149
本文介绍了发送STDERR /标准输出信息的功能,并捕获退出信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

进出口工作的错误处理和日志记录在我的bash脚本。下面我已经包括简化code片段,体现了用例。

我要实现我的脚本如下:


    在下面的code
  1. 捕获退出信号,这将引发onexit()函数
  2. stderr和标准输出应该发送到日志()函数,这将确保根据特定的日志格式(在下面的例子中简化的)
  3. 来输出记录到一个记录文件

问题与当前的code如下:


  • 第1步不被onexit功能捕获,脚本继续第2步。最有可能的,因为标准错误管道输送到logStd()。我如何发送错误信息到logStd(),但仍陷阱的退出信号onexit()?

分辨率:


  1. 添加设置-o pipefail

  2. 通过增加对 onexit()获取退出状态本地EXIT_STATUS = $ {1: - $}

script.sh(分辨率后编辑)

 #!/斌/ bash的-E
设置-o pipefail#执行程序退出看家
功能onexit {
    当地EXIT_STATUS = $ {1: - $}?
    日志onexit()调用参数:$ EXIT_STATUS
    退出$ 1
}#发送的输入参数呼应简化的日志功能。此功能是该脚本中使用
#在实际情况下,该功能会发送日志语句根据特定的日志格式日志文件
功能日志{
    回声的log():$ 1
}#简化日志功能读取输入流发送到日志
#这个功能是从命令一起使用
功能logStd {
    日志logStd()被称为
    而IFS =读-r线;做日志$行; DONE
}#http://linuxcommand.org/wss0160.php
#陷阱命令允许你当通过脚本接收到信号执行命令。
#用途:陷阱ARG信号
#信号是信号列表拦截和ARG是执行一个命令时,接收到的信号中的一个
#精氨酸可以是一个命令或者象下面CLEAN_UP函数名
陷阱onexit 1 2 3 15 ERR#第1步 - 失败,错误发送到logstd()和onexit被困()
登录** Tarballing失败,文件doesn't存在
焦油-czf /Users/ismar.slomic/shellscripting/unknownfile.txt.gz /Users/ismar.slomic/shellscripting/unknownfile.txt 2 - ;&放大器; 1 | logStd#第2步 - 要成功运行并发送:以logStd焦油去除成员名称领先'/'()
登录** Tarballing应该成功运行
焦油-czf /Users/ismar.slomic/shellscripting/file.txt.gz /Users/ismar.slomic/shellscripting/file.txt 2 - ;&放大器; 1 | logStdonexit

输出

 日志():** Tarballing失败,文件doesn't存在
日志():logStd()呼吁
日志():焦油:/Users/ismar.slomic/shellscripting/unknownfile.txt:无法统计:没有这样的文件或目录
日志():焦油:错误退出previous错误延迟。
日志():** Tarballing应该成功运行
日志():logStd()呼吁
日志():焦油:删除'/'开头的成员名称
日志():onexit()调用参数:


解决方案

您必须使用

 设置-o pipefail

请参阅此<一个href=\"http://stackoverflow.com/questions/27546819/bash-trap-err-does-not-work-when-pipe-operator-is-used\">related StackOverflow的问题。


小例子

 #!/斌/庆典陷阱处理程序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 StackOverflow 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

这篇关于发送STDERR /标准输出信息的功能,并捕获退出信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆