systemd 的 StandardOutput 选项不起作用

Fre*_*ang 3 linux systemd

我正在使用systemd在启动时启动一个程序并让它在后台运行。

我编写了一个简单的脚本systemd来调用,该脚本将打印几行我希望在终端中看到的日志。

所以我StandardOutput=journal+console在服务配置中进行了设置,但在终端和日志中都看不到输出。

frederick@Frederick-PC:~$ sudo systemctl start my_program.service
frederick@Frederick-PC:~$ journalctl _SYSTEMD_UNIT=my_program.service
No journal files were found.
-- No entries --
Run Code Online (Sandbox Code Playgroud)

这些是我的服务配置和脚本。

/etc/systemd/system/my_program.service

[Unit]
Description=Start my_program client after system is booted

[Service]
Type=forking
ExecStart=/usr/bin/my_program.sh start
ExecStop=/usr/bin/my_program.sh stop
PIDFile=/run/my_program.pid
WorkingDirectory=/home/frederick/Applications/my_program-go/
StandardOutput=journal+console

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

/usr/bin/my_program.sh

#!/bin/sh

start() {
    if [ -f /run/my_program.pid ]; then
        kill -0 $(cat /run/my_program.pid) > /dev/null 2>&1
        if [ $? -eq 0 ]; then
            echo "my_program has been already started"
            exit 1
        fi
    fi
    echo -n "Starting my_program... "
    nohup /home/frederick/Applications/my_program-go/my_program-local -c /home/frederick/Applications/my_program-go/config.json >> /home/frederick/Applications/my_program-go/my_program.log 2>&1 &
    if [ $? -gt 0 ]; then
        echo "failed"
        rm /run/my_program.pid > /dev/null 2>&1
    else
        echo $! | tee /run/my_program.pid
    fi
}

stop() {
    if [ -f /run/my_program.pid ]; then
        echo -n "Stopping my_program... "
        msg=$(kill $(cat /run/my_program.pid) 2>&1)
        if [ $? -gt 0 ]; then
            echo "failed"
            echo $msg
        else
            rm /run/my_program.pid > /dev/null 2>&1
            echo "succeeded"
        fi
    else
        echo "my_program not started"
    fi
}

restart() {
    stop
    start
}

case $1 in
    start|stop|restart)
        "$1"
        ;;
    *)
        echo "No such operation"
        exit 1
        ;;
esac
Run Code Online (Sandbox Code Playgroud)

我怎样才能看到echo脚本中打印的那些行?请帮忙,谢谢。

Jde*_*eBP 7

我写了一个简单的脚本让 systemd 调用……

……这就是问题的根源。您的“简单脚本”覆盖了标准输出和标准错误的发送位置。这完全没有必要。所有重定向、PID 文件写入、nohup-ing 和分叉对于已经被守护程序化并且服务管理器已经知道其 PID 的东西是完全没有必要的。您根本不需要该脚本的任何部分。相反,像这样编写你的服务单元:

[单元]
说明=系统启动后启动 my_program 客户端

[服务]
类型=简单
ExecStart=/home/frederick/Applications/my_program-go/my_program-local -c /home/frederick/Applications/my_program-go/config.json
WorkingDirectory=/home/frederick/Applications/my_program-go/
标准输出=日志+控制台

[安装]
WantedBy=multi-user.target

调用任何必要的选项来阻止你的程序分叉,除非它确实实现了分叉准备协议。很少有程序真正做到这一点。您的“简单脚本”当然没有,因为它在守护进程初始化并准备就绪之前很久就退出了父进程。

进一步阅读

  • 乔纳森·德·博因·波拉德 (2015)。恐怖的系统屋。经常给出答案。
  • Systemd 启动后立即终止服务
  • Yocto linux 服务脚本问题
  • systemd.exec手册页(也systemd.servicesystemd.unit)。手册页说:服务、套接字、挂载点和交换设备的单元配置文件共享定义生成进程的执行环境的配置选项子集。本手册页列出了这四种单元类型共享的配置选项。