将bash中的子脚本错误重定向到父脚本中的函数

问题描述 投票:0回答:1

我想将bash脚本中我的java调用(直线)的错误重定向到同一个bash脚本中的函数。怎么做到呢?

beeline -u "${!DestHiveJdbcUrl}" -n hive -p hive -e "use $DatabaseName ; MSCK REPAIR TABLE $TableName" 2>&1 | PrtLog e

我想记录错误

"Error: Error while compiling statement: FAILED: SemanticException [Error 10072]: Database does not exist: prod_corporate_parameters_tets (state=42000,code=10072)"

PrtLog是我的函数,e是一个表示我的函数的参数,这是一个错误。但我的上述方法不起作用。任何想法,我错了?我的PrtLog功能如下。 Msg变量捕获日志消息。

    PrtLog() {
        Msg=$2
        case $1 in
        'i')
                Severity='INFO '
                ThisCode=0
                lLevel=10
                ;;
        'e')
                Severity='ERROR'
                ThisCode=1
                lLevel=0
                ;;
        'd')
                Severity='DEBUG'
                ThisCode=0
                lLevel=30
                ;;
        'w')
                Severity='WARN '
                ThisCode=0
                lLevel=20
                ;;
        't')
                Severity='TRACE'
                ThisCode=0
                lLevel=40
                ;;
        *)
                Severity='UNKWN'
                ThisCode=1
                lLevel=0
                ;;
        esac

   if [ $RetCode -lt $ThisCode ]; then
      RetCode=$ThisCode
   fi
   if [ $lLevel -le $vDebLevel ]; then
      echo `date "+%Y/%m/%d %H:%M:%S"` - `hostname` - $ScrName - $vPid - "$Severity" - $Msg | tee -a ${LogFile}
   fi
}
bash io-redirection
1个回答
0
投票

无论它是什么,你都称之为直线:

beeline -u "${!DestHiveJdbcUrl}" -n hive -p hive -e "use $DatabaseName ; MSCK REPAIR TABLE $TableName" 2>&1 | PrtLog e

和beeline最终产生一个错误消息,你将它与stdout结合并将它传递给函数PrtLog,你可以用参数e调用它。

现在PrtLog需要2个参数,Msg和案例切换器,它是'e':

PrtLog(){Msg = $ 2案例'e'中的$ 1)严重性='错误'ThisCode = 1 lLevel = 0 ;; ESAC

然后我们有

   if [ $RetCode -lt $ThisCode ]; then
      RetCode=$ThisCode
   fi
   if [ $lLevel -le $vDebLevel ]; then
      echo `date "+%Y/%m/%d %H:%M:%S"` - `hostname` - $ScrName - $vPid - "$Severity" - $Msg | tee -a ${LogFile}
   fi

我们不知道什么是RetCode,它没有记录。第一个分支后可能是ThisCode,应该是1。

lLevel为0,应根据vDebLevel进行检查。我们不知道,vDebLevel是什么。全局变量。

然后我们有了过时的古老反复调用,这里没关系,比如$(主机名),未知的东西,$ Severity现在应该是Error,而$ Msg是空的,因为我们只有一个参数,请记住:

... | PrtLog e 

这是通过管道附加到某些LogFile的tee。

Msg变量捕获日志消息。

不,它没有。 Msg是函数期望的第二个参数,但是使用一个参数调用。

要么捕获beeprogram的输出:

msg=$(beeline -u "${!D...l}" -n hive -p hive -e "use ..." 2>&1)
PrtLog e "msg"

或者您将程序的输出传递给函数,但该函数必须从STDIN读取:

while ... 
   read line 
   ... do something with $line
done

您不能指望函数在输入位置期望参数,反之亦然。

你的问题与直线无关。学会识别您的问题。

要重现该问题,您只需要一个程序,它在stdout和stderr上生成输出:

#!/bin/bash
#
# write to err and out
#
echo "error" >&2; 
echo "output"

我们称之为beelinemock.sh。

chmod a+x beelinemock.sh
./beelinemock.sh 
error
output

测试,是否有效:

./beelinemock.sh 2>/dev/null
output

./beelinemock.sh 1>/dev/null
error

对?

现在把它作为PrtLog的来源:

./beelinemock.sh  2>&1 | PrtLog e

现在简化整个脚本,只需为RetCode和vDebLevel尝试一些随机数:

LogFile=prtlog.log
RetCode=33
vDebLevel=7

PrtLog() {
        Msg=$2
        case $1 in
        'e')
                Severity=ERROR
                ThisCode=1
                lLevel=0
                ;;
       esac

       if [ $RetCode -lt $ThisCode ]; then
          RetCode=$ThisCode
       fi
       if [ $lLevel -le $vDebLevel ]; then
          echo $(date "+%Y/%m/%d %H:%M:%S") - $(hostname) - "$Severity" - $Msg | tee -a ${LogFile}
       fi
}

./beelinemock.sh  2>&1 | PrtLog e

输出:

2018/03/05 15:46:37 - tux201t - ERROR -

没有消息,正如所料。

修改最后一行:

msg=$(./beelinemock.sh  2>&1)
PrtLog e "$msg"

输出:

2018/03/05 15:48:17 - tux201t - ERROR - error output

这是消息。

带管道:

LogFile=prtlog.log
RetCode=33
vDebLevel=7

PrtLog() {
        case $1 in
        'e')
                Severity=ERROR
                ThisCode=1
                lLevel=0
                ;;
       esac

       if [ $RetCode -lt $ThisCode ]; then
          RetCode=$ThisCode
       fi
       if [ $lLevel -le $vDebLevel ]; then {
          echo $(date "+%Y/%m/%d %H:%M:%S") - $(hostname) - "$Severity" - $Msg

          while read line
          do
            echo $line
          done

       } | tee -a ${LogFile}
       fi
}

./beelinemock.sh  2>&1 | PrtLog e

输出:

2018/03/05 15:50:56 - tux201t - ERROR -
error
output

没有人愿意在他的数据上发出“MSCK REPAIR $ Tablename”来测试你的脚本。随着“直线”,你失去了90%的观众“不知道,不能帮助”,所以人们离开,因为你需要通过代码工作5分钟或更长时间才能找到答案,这与句法非常无关问题的一部分,当然,它是在语义层面上。

© www.soinside.com 2019 - 2024. All rights reserved.