在 bash 脚本文件中登录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46471979/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 16:29:29  来源:igfitidea点击:

Logging inside a bash script file

linuxbashshelllogging

提问by zlobul

I have a pretty large script ( functions contains around 4000 lines of code) . Here is a part of it :

我有一个非常大的脚本(函数包含大约 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   ;;
    2)echo   ;;                                       
    3)echo   ;;

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

I want to log the commands executed in the script.

我想记录脚本中执行的命令。

What I have tried so far is :

到目前为止我尝试过的是:

  1. #!/bin/bash -x--> this will log all the output , but will also "spam" the logs with unneeded information like variable values etc. However this seems to be the best way so far...
  2. I have tried #!/bin/bash -i, enabling history with set -o history . The disadvantage of this is it will log everything . When I call the function file for example it will log every single line as if it was executed .
  3. I have tried creating a log function :

    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
    }
    

    This seems to work most of the time. But when I do, for example:

    case $OPTION in
        1) logthis "some_function 1 2 3" ;;  
        2) some_function 2 1 3 ;;
        3) some_function 3 1 2 ;;
    esac
    
  1. #!/bin/bash -x--> 这将记录所有输出,但也会用不需要的信息(如变量值等)“垃圾邮件”日志。然而,这似乎是迄今为止最好的方法......
  2. 我已经尝试过 #!/bin/bash -i,使用 set -o history 启用历史记录。这样做的缺点是它会记录所有内容。例如,当我调用函数文件时,它将记录每一行,就像它被执行一样。
  3. 我曾尝试创建日志功能:

    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
    }
    

    这似乎在大多数情况下都有效。但是当我这样做时,例如:

    case $OPTION in
        1) logthis "some_function 1 2 3" ;;  
        2) some_function 2 1 3 ;;
        3) some_function 3 1 2 ;;
    esac
    

it will not work as I will lose the arguments 1 2 3

它不会起作用,因为我会失去参数 1 2 3

Do you have any other ideas of doing an elegant logging system inside a bash script?

在 bash 脚本中做一个优雅的日志系统,你还有什么其他想法吗?

回答by John Kugelman

Get rid of the evalin your log function. Just write "$@"to execute the passed command.

摆脱eval日志功能中的 。只需写入"$@"以执行传递的命令。

logthis() {
    echo "$(date): $@" >> "$historyfile"
    "$@" 2>> "$historyfile"
}

Then you can log a command by simply prepending logthis. No need for extra quotes.

然后,您可以通过简单地添加 来记录命令logthis。不需要额外的报价。

logthis some_function 1 2 3

This will very nicely preserve all the arguments--even if they have whitespace or other special characters.

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

I'd recommend a minor improvement to the echocommand as well. If you use printf %qit'll log arguments with whitespace better.

我还建议对echo命令进行小幅改进。如果你使用printf %q它会更好地记录带有空格的参数。

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

回答by Paul Hodges

Try set -v

尝试 set -v

That doesn't parse the commands like set -x, just outputs what gets executed.

这不会解析像 那样的命令set -x,只是输出执行的内容。

set -v
: all the things 'in' 
{ # after setup to parse args, set vars & traps, declare funcs, etc
  your bulk code here
} 2>&1 | tee /some/file.log
, 'yay!'

outputs exactly : all the things 'in' $0, 'yay!'
Doesn't even parse $0.

完全输出: all the things 'in' $0, 'yay!'
甚至不解析 $0。

Arguments recorded, minimal spam. ;)

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

Consider wrapping curlies around the main block of code to manage output logging.

考虑在主要代码块周围包裹卷曲以管理输出日志记录。

##代码##

You can save the set -xspam for --verbosemode. ;)

您可以set -x--verbose模式保存垃圾邮件。;)