背景
- 在linux系统中,当调用.sh脚本时,脚本中的标准输出原本是打印到控制台的,我们可以将其打印到某个文件,并添加上时间戳,方便问题溯源。
- 有时我们运行的脚本是.py脚本,也需要将输出映射到日志文件。
解决办法
调用.sh脚本时
- 假设我的目标脚本名为script.sh脚本,我需要写一个start.sh脚本,在该脚本中启动script.sh脚本,并将script.sh脚本的输出保存到out_log.txt文件中,过程如下:
- 首先安装moreutils包:
sudo apt-get update
sudo apt-get install moreutils
- 编写 start.sh 脚本:这个脚本将启动 script.sh 并处理日志重定向和时间戳添加。
./script.sh 2>&1 | ts '[%Y-%m-%d %H:%M:%S]' >> out_log.txt
- 如果不安装moreutils包,将start.sh改为如下内容即可:
(
while IFS= read -r line
do
echo "$(date '+[%Y-%m-%d %H:%M:%S]') $line"
done < <(./script.sh 2>&1)
) >> out_log.txt &
#!/bin/sh
echo "Script started"
echo "Doing some work..."
sleep 2
echo "Work done"
echo "Script finished"
[2024-06-06 12:00:00] Script started
[2024-06-06 12:00:00] Doing some work...
[2024-06-06 12:00:02] Work done
[2024-06-06 12:00:02] Script finished
调用.py脚本时
- 我们新建一个运行目标start.sh的启动脚本如下:
current_time=$(date +"%Y-%m-%d-%H-%M-%S")
echo "${current_time} start python3:\n" >>output.log
nohup python3 Test1.py &
echo $! > pid_file.txt
- 在start.sh脚本中启动目标的.py文件。在.py脚本中,加入以下命令使能将print打印到日志文件:
PrintToFile = True
if PrintToFile:
logging.basicConfig(filename='output.log', level=logging.INFO, format='%(asctime)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
def redirect_stdout_to_log():
class StdOutLogger(object):
def write(self, message):
logging.info('%s %s', datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), message.rstrip())
def flush(self):
pass
sys.stdout = StdOutLogger()
redirect_stdout_to_log()
- 并将该进程号保存在一个pid_file.txt中。当我们后面想停止该进程时,直接运行以下stop.sh脚本即可:
pid=$(cat pid_file.txt)
kill $pid