El *_*opo 2 linux bash shell logging
我有一个很大的脚本(函数包含大约4000行代码)。这是它的一部分:
#!/bin/bash
. ./functions > /dev/null 2>&1
some_function(){
while true
do
CHOICE=$(whiptail --menu "\n\n\n\n\n\n\n\n" --title "Tools" --nocancel $window 20 \
"1" "Option1" \
"2" "Option2" \
"3" "Option3" 3>&1 1>&2 2>&3)
case $CHOICE in
1)echo $1 $2 $3;;
2)echo $2 $1 $3;;
3)echo $3 $2 $1;;
esac
done
}
while true; do
arr=()
for ((n=1; n<=$node_num; n++))
do
node+=($n NODE$n)
done
OPTION=$(whiptail --menu "\n\n\n\nPlease choose:\n\n\n" --title "tools" $window 20 "${node[@]}" \
case $OPTION in
1) some_function 1 2 3 ;;
2) some_function 2 1 3 ;;
3) some_function 3 1 2 ;;
esac
done
Run Code Online (Sandbox Code Playgroud)
我想记录脚本中执行的命令。
到目前为止,我尝试过的是:
#!/bin/bash -x ->这将记录所有输出,但也会使用不必要的信息(例如变量值等)对日志进行“垃圾邮件”处理。但是,这似乎是迄今为止最好的方法... #!/bin/bash -i使用set -o history启用历史记录。这样做的缺点是它将记录所有内容。例如,当我调用函数文件时,它将记录每一行,就好像它已执行一样。我尝试创建一个日志功能:
logthis(){
## print the command to the logfile
echo "$(date) $@" >> $historyfile
## run the command and redirect it's error output
## to the logfile
eval "$@" 2>> $historyfile
}
Run Code Online (Sandbox Code Playgroud)
这似乎在大多数时间都有效。但是当我这样做时,例如:
case $OPTION in
1) logthis "some_function 1 2 3" ;;
2) some_function 2 1 3 ;;
3) some_function 3 1 2 ;;
esac
Run Code Online (Sandbox Code Playgroud)它不会起作用,因为我会丢失参数1 2 3
您还有其他想法可以在bash脚本中进行优雅的日志记录吗?
摆脱eval您的日志功能。只需编写"$@"即可执行传递的命令。
logthis() {
echo "$(date): $@" >> "$historyfile"
"$@" 2>> "$historyfile"
}
Run Code Online (Sandbox Code Playgroud)
然后,您只需简单地添加即可记录命令logthis。无需额外的报价。
logthis some_function 1 2 3
Run Code Online (Sandbox Code Playgroud)
这将很好地保留所有参数-即使它们具有空格或其他特殊字符。
我还建议对echo命令进行一点改进。如果使用printf %q它,则可以更好地使用空格记录参数。
echo "$(date):$(printf ' %q' "$@")" >> "$historyfile"
Run Code Online (Sandbox Code Playgroud)