简体   繁体   English

记录到文件并为每个命令添加时间戳 bash 脚本

[英]Logging to a file and adding timestamps to every single command bash script

I'm writing a bash script that integrates with several modules and call several scripts (python, js, etc).我正在编写一个 bash 脚本,它集成了多个模块并调用了多个脚本(python、js 等)。 I want to log everything (from bash, from the python/js scripts) to one single log file, and add timestamps to it.我想将所有内容(从 bash,从 python/js 脚本)记录到一个日志文件,并向其添加时间戳。

So, say my Bash script is called bash-script.sh , my Python script is called python-script.py and my js script is js-script.js .因此,假设我的 Bash 脚本名为bash-script.sh ,我的 Python 脚本名为python-script.py ,我的 js 脚本为js-script.js The log file is out.log日志文件是out.log

Now, I'll split this question into two.现在,我将把这个问题分成两个。

Part I:第一部分:

To log every single command in the bash script and add timestamps to it, bash-script.sh begins with the following:要记录 bash 脚本中的每个命令并为其添加时间戳, bash-script.sh以以下内容开头:

#!/bin/bash
source ~/.bashrc

exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1> out.log 2>&1
exec > >(while IFS= read -r line; do printf '%s %s %s\n' "$(date --rfc-3339=seconds)" "[Bash-script]" "$line"; done 3>out.log)

The problem is, the script is adding timestamps to everything, including newlines.问题是,脚本正在为所有内容添加时间戳,包括换行符。 In addition, since I'm calling external scripts, it is adding some symbols that makes the whole thing super ugly.此外,由于我正在调用外部脚本,它添加了一些符号,使整个事情变得非常难看。 Here's an example of an output:这是 output 的示例:

022-05-18 16:37:01+00:00 [Bash-script] Bash script started!
2022-05-18 16:37:01+00:00 [Bash-script] Stopping all services
2022-05-18 16:37:02+00:00 [Bash-script] ● srv1.service - Service1 
2022-05-18 16:37:02+00:00 [Bash-script]   Drop-In: /etc/systemd/system/
2022-05-18 16:37:06+00:00 [Bash-script]
2022-05-18 16:37:06,232 [MainThread] INFO [python-script] In python-script.py

I want to get rid of the newlines and symbols (●)我想去掉换行符和符号 (●)

In addition, I have a function WaitForServices that I run after starting a list of services and it basically waits (by sleeping x amount of seconds) until all services are up completely.此外,我有一个 function WaitForServices ,它在启动服务列表后运行,它基本上等待(通过休眠 x 秒)直到所有服务完全启动。 Until then, it keeps printing waiting for services x .在那之前,它一直打印waiting for services x

The log entries in the out.log file these 'waiting' prints are just echo'd without a timestamp. out.log文件中的日志条目这些“等待”打印只是回显而没有时间戳。 Output example: Output 示例:

* Im not even sure it makes sense with the done 3>out.log, pls correct me if it's wrong. *我什至不确定 done 3>out.log 是否有意义,如果有误,请纠正我。

Part II第二部分

Since I want to integrate with other scripts such as python and js, and write to the same log, I'm redirecting the output with >> and I'm not sure it is a good practice.由于我想与其他脚本(例如 python 和 js)集成,并写入同一日志,因此我使用 >> 重定向 output,我不确定这是一个好的做法。 I also want the bash script to exit completely if the python or the js scripts returns an error (exit code that diff than 0).如果 python 或 js 脚本返回错误(退出代码不同于 0),我还希望 bash 脚本完全退出。 That's how I currently do it:这就是我目前的做法:

bash-script.sh : bash-script.sh

#!/bin/bash
source ~/.bashrc
    
    exec 3>&1 4>&2
    trap 'exec 2>&4 1>&3' 0 1 2 3
    exec 1> out.log 2>&1
    exec > >(while IFS= read -r line; do printf '%s %s %s\n' "$(date --rfc-3339=seconds)" "[Bash-script]" "$line"; done 3>out.log)

function exitCode {
  if [ "$?" != "0" ];then
      echo Exiting...
      exit;
  fi
}

.....code
.....code

PYTHONPATH=.. /path-to-virtual-env/python python-script.py  >> out.log ; exitCode $?

.....more code

sudo node /path-to-js-file/js-script.js  >> out.log ; exitCode $?

.....more code

Now, I'm pretty sure it is stupid but I couldn't find any other way to achieve it.现在,我很确定这是愚蠢的,但我找不到任何其他方法来实现它。 I am using the logging lib in the python script but when I specify filename=out.log (which is in the same dir) nothing really happens.我在 python 脚本中使用日志记录库,但是当我指定 filename=out.log(在同一目录中)时,什么都没有发生。

logging.basicConfig(filename='out.log',format="%(asctime)s %(levelname)s [%(module)s] %(message)s", level=logging.INFO, force=True)

Thank you very much for any help非常感谢您的帮助

I'm not sure if this could work, but what if you had another bash script, which ran the first bash script and piped the output to something like ets , which would automatically timestamp every line.我不确定这是否可行,但如果您有另一个 bash 脚本,该脚本运行第一个 bash 脚本并将 output 通过管道传输到类似ets的东西,它会自动为每一行加上时间戳。

/path/to/bash-script.sh 2>&1 | ets -f "[%F %T] [bash-script]"
/path/to/python-script.py 2>&1 | ets -f "[%F %T] [python-script]"
/path/to/js-script.js 2>&1 | ets -f "[%F %T] [js-script]"

The current road you're going down is very confusing and complex.你目前走的路非常混乱和复杂。 This obviously doesn't get rid of blank lines, etc. You'd need a separate script to parse that out later, I'm thinking.这显然并没有消除空行等。我想你需要一个单独的脚本来稍后解析它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM