Linux 在bash脚本文件中进行日志记录

Linux 在bash脚本文件中进行日志记录,linux,bash,shell,logging,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" "Op

我有一个相当大的脚本(函数包含大约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
这似乎在大多数情况下都有效。但当我这样做时,例如:

case $OPTION in
    1) logthis "some_function 1 2 3" ;;  
    2) some_function 2 1 3 ;;
    3) some_function 3 1 2 ;;
esac
它将不起作用,因为我将丢失参数1 2 3


对于在bash脚本中实现一个优雅的日志系统,您还有其他想法吗

去掉日志函数中的
eval
。只需编写
“$@”
即可执行传递的命令

logthis() {
    echo "$(date): $@" >> "$historyfile"
    "$@" 2>> "$historyfile"
}
然后,只需在
logthis
前面加上前缀,即可记录命令。不需要额外的报价

logthis some_function 1 2 3
这将很好地保留所有参数——即使它们有空格或其他特殊字符

我还建议对
echo
命令做一点小小的改进。如果您使用
printf%q
,它将更好地用空格记录参数

echo "$(date):$(printf ' %q' "$@")" >> "$historyfile"

尝试
设置-v

它不解析像
set-x
这样的命令,只输出执行的命令

set -v
: all the things 'in' $0, 'yay!'
精确地输出
:所有的东西都在$0中,耶
甚至不解析$0

已记录参数,垃圾邮件最少。;)

考虑在主代码块周围缠绕卷曲以管理输出日志记录

{ # after setup to parse args, set vars & traps, declare funcs, etc
  your bulk code here
} 2>&1 | tee /some/file.log

您可以将
设置-x
垃圾邮件保存为
--verbose
模式

可以根据需要在脚本中使用
set-x
set+x
启用和禁用跟踪;它是选项1的细粒度版本。选项2不需要
-i
选项;默认情况下,在交互式shell中启用历史记录,但不需要交互式shell。是的,我可以启用和禁用调试模式,但正在寻找更优雅的方式,而不是遍历所有代码和设置set-x/set+x。这里有一个完整的bash日志记录实现:最后一点,为什么不直接使用printf呢?
printf
将为每个额外参数重复格式字符串。无法执行此操作并在一个
printf
中打印日期。不幸的是,当我尝试传递变量时,例如:logthis command$1$2发生故障,whiptail窗口不显示…:/如果你仍然有问题,你应该写一个关于鞭子的问题。我不熟悉它。这里有一个链接,指向我找到的关于whiptail的内容:,因此whiptail似乎正在切换fd,这使得在所有情况下都无法使用logthis功能。谢谢,但这仍然会记录所有whiptail菜单,例如。我不能像变量声明那样将它们输出到/dev/null。您能将菜单抽象为一个函数,该函数在开始时关闭-v,在结束时打开吗?您要求的是细粒度日志记录,因此我担心您将不得不编写细粒度代码。
{ # after setup to parse args, set vars & traps, declare funcs, etc
  your bulk code here
} 2>&1 | tee /some/file.log