我想将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
}
无论它是什么,你都称之为直线:
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分钟或更长时间才能找到答案,这与句法非常无关问题的一部分,当然,它是在语义层面上。