如何将从systemd服务中的bash脚本调用的python脚本的输出重定向到控制台和文件?

如何将从systemd服务中的bash脚本调用的python脚本的输出重定向到控制台和文件?,python,bash,systemd,tee,Python,Bash,Systemd,Tee,我定期从Centos 7服务器上部署的计时器生成systemd服务。ExecStart指令正在调用bash脚本,其输出使用tee-a重定向到控制台和文件。Bash脚本是调用python脚本的包装器 奇怪的是,即使我可以使用journalctl-xe-u my_service_name看到bash脚本(包装器)输出和Python脚本输出,日志文件中也没有Python脚本的输出,只有bash命令的输出 系统服务 # my_service.service [Unit] Description=My

我定期从Centos 7服务器上部署的计时器生成systemd服务。ExecStart指令正在调用bash脚本,其输出使用
tee-a
重定向到控制台和文件。Bash脚本是调用python脚本的包装器

奇怪的是,即使我可以使用
journalctl-xe-u my_service_name
看到bash脚本(包装器)输出和Python脚本输出,日志文件中也没有Python脚本的输出,只有bash命令的输出

系统服务

# my_service.service

[Unit]
Description=My service
Wants=my_service.timer

[Service]
ExecStart=/bin/bash -c '/opt/services/my_service/my_service.sh | tee -a /var/log/my_service/my_service.log'
RuntimeDirectory=my_service
WorkingDirectory=/opt/services/my_service

[Install]
WantedBy=multi-user.target
Bash脚本

#!/bin/bash

# my_service.sh (Bash wrapper for python script)

echo "My Bash script starts"
script_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
python3 -m venv "${script_dir}/venv"
. "${script_dir}/venv/bin/activate"

python my_service.py 

echo "My Bash script ends"
# my_service.py (called by Bash wrapper)

import logging
import sys

logger = logging.getLogger(os.path.basename(sys.argv[0]))
logger.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('[%(asctime)s] [%(process)d] [%(levelname)s] (%(name)s) %(message)s',datefmt='%Y-%m-%d %H:%M:%S %z')
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)

logger.info("My python script {} starts".format(os.path.basename(sys.argv[0])))
logger.info("My python script {} ends".format(os.path.basename(sys.argv[0])))
# journalctl -xe -u my_service

-- Unit my_service.service has finished start-up with result done
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: My Bash script starts
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: [2021-0X-0X XX:XX:00 +0XXX] [19149] [INFO] My python script my_service.py starts 
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: [2021-0X-0X XX:XX:00 +0XXX] [19149] [INFO] My python script my_service.py ends 
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: My Bash script ends
-- Subject: Unit my_service.service has finished start-up
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
# /var/log/my_service/my_service.log

My Bash script starts
My Bash script ends
Python脚本

#!/bin/bash

# my_service.sh (Bash wrapper for python script)

echo "My Bash script starts"
script_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
python3 -m venv "${script_dir}/venv"
. "${script_dir}/venv/bin/activate"

python my_service.py 

echo "My Bash script ends"
# my_service.py (called by Bash wrapper)

import logging
import sys

logger = logging.getLogger(os.path.basename(sys.argv[0]))
logger.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('[%(asctime)s] [%(process)d] [%(levelname)s] (%(name)s) %(message)s',datefmt='%Y-%m-%d %H:%M:%S %z')
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)

logger.info("My python script {} starts".format(os.path.basename(sys.argv[0])))
logger.info("My python script {} ends".format(os.path.basename(sys.argv[0])))
# journalctl -xe -u my_service

-- Unit my_service.service has finished start-up with result done
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: My Bash script starts
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: [2021-0X-0X XX:XX:00 +0XXX] [19149] [INFO] My python script my_service.py starts 
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: [2021-0X-0X XX:XX:00 +0XXX] [19149] [INFO] My python script my_service.py ends 
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: My Bash script ends
-- Subject: Unit my_service.service has finished start-up
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
# /var/log/my_service/my_service.log

My Bash script starts
My Bash script ends
日志TL输出

#!/bin/bash

# my_service.sh (Bash wrapper for python script)

echo "My Bash script starts"
script_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
python3 -m venv "${script_dir}/venv"
. "${script_dir}/venv/bin/activate"

python my_service.py 

echo "My Bash script ends"
# my_service.py (called by Bash wrapper)

import logging
import sys

logger = logging.getLogger(os.path.basename(sys.argv[0]))
logger.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('[%(asctime)s] [%(process)d] [%(levelname)s] (%(name)s) %(message)s',datefmt='%Y-%m-%d %H:%M:%S %z')
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)

logger.info("My python script {} starts".format(os.path.basename(sys.argv[0])))
logger.info("My python script {} ends".format(os.path.basename(sys.argv[0])))
# journalctl -xe -u my_service

-- Unit my_service.service has finished start-up with result done
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: My Bash script starts
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: [2021-0X-0X XX:XX:00 +0XXX] [19149] [INFO] My python script my_service.py starts 
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: [2021-0X-0X XX:XX:00 +0XXX] [19149] [INFO] My python script my_service.py ends 
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: My Bash script ends
-- Subject: Unit my_service.service has finished start-up
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
# /var/log/my_service/my_service.log

My Bash script starts
My Bash script ends
日志文件内容

#!/bin/bash

# my_service.sh (Bash wrapper for python script)

echo "My Bash script starts"
script_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
python3 -m venv "${script_dir}/venv"
. "${script_dir}/venv/bin/activate"

python my_service.py 

echo "My Bash script ends"
# my_service.py (called by Bash wrapper)

import logging
import sys

logger = logging.getLogger(os.path.basename(sys.argv[0]))
logger.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('[%(asctime)s] [%(process)d] [%(levelname)s] (%(name)s) %(message)s',datefmt='%Y-%m-%d %H:%M:%S %z')
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)

logger.info("My python script {} starts".format(os.path.basename(sys.argv[0])))
logger.info("My python script {} ends".format(os.path.basename(sys.argv[0])))
# journalctl -xe -u my_service

-- Unit my_service.service has finished start-up with result done
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: My Bash script starts
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: [2021-0X-0X XX:XX:00 +0XXX] [19149] [INFO] My python script my_service.py starts 
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: [2021-0X-0X XX:XX:00 +0XXX] [19149] [INFO] My python script my_service.py ends 
feb. 0X 0X:XX:00 jenkins.hksiop.local bash[19140]: My Bash script ends
-- Subject: Unit my_service.service has finished start-up
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
# /var/log/my_service/my_service.log

My Bash script starts
My Bash script ends

我错过了什么?为什么journalctl日志显示bash输出+Python输出,而我的日志文件只显示bash输出?如何将bash和python脚本输出写入我的日志文件?

能否尝试使用无缓冲输出运行python
python-u script.py
或在包装程序bash脚本中设置环境变量
export pythonunbuffer=0
。@Alexandre Juma:我尝试了这两种方法(-u和环境变量),但写入日志文件的输出是相同的,只有bash“echo”是writensorry,太像触发器指针了。您使用的是日志框架,而不是直接使用stdout/stderr。您需要将日志处理程序挂接到日志框架。请看这里: