如何调试 systemd 下的旧 initd 脚本?

如何调试 systemd 下的旧 initd 脚本?

我有一个较旧的 initd 脚本来启动我的应用程序。它在旧版本的 SuSE 下运行良好,但在 Open SuSE 12.3 上失败。

奇怪的是

cd /etc/init.d ; ./script start

工作正常。

/etc/init.d/script start

显示到 systemctl 的重定向,但没有启动我的应用程序(也没有显示来自 initd 脚本的任何输出)。

我没有看到任何日志条目显示哪里出了问题。我看到的唯一条目是在 /var/log/messages 中,表明应用程序已启动。

我该如何调试这个?

答案1

脚本出现这种行为的原因是 OpenSuse 12.3 已用 systemd(控制整个启动过程的系统管理守护程序)替换了旧的 sysvinit。

描述 systemd 启动的服务的脚本格式与 sysvinit 的格式不同,因此脚本失败也就不足为奇了。正确设置脚本后,通过 systemctl 进行操作就很简单了:

sudo systemctl enable/disable your-service

启用或禁用它,通常

sudo systemctl start/stop/status your-service

启动它、停止它、查询它的状态。

典型的自定义服务脚本位于文件夹 /etc/systemd/system 中,以后缀 .service 结尾,格式如下:

 [Unit]
 Description=sdbarker.com Chiliproject
 Requires=mysqld.service nginx.service
 Wants=mysqld.service nginx.service

 [Service]
 User=www-data
 WorkingDirectory=/path/to/chiliproject/install
 ExecStart=/usr/bin/bundle 
 PIDFile=/path/to/chiliproject/install/tmp/pids/server.pid

 [Install]
 WantedBy=multi-user.target

如您所见,大多数条目都是不言自明的。如果不了解有关您的脚本的更多信息,我无法提供进一步的帮助,但您会发现在这个 Arch Linux Wiki 页面中编写适当的自定义服务脚本所需的信息。

答案2

有几件事。

  1. 在干净的环境下运行命令:

    env -i PATH=/usr/sbin:/sbin:/usr/bin:/bin /etc/init.d/SCRIPT start
    
  2. 第二步,打开 shell 调试。一个简单的方法是:

    bash -x SCRIPT start
    

结合两者,可得到:

    env -i PATH=/usr/sbin:/sbin:/usr/bin:/bin bash -x /etc/init.d/SCRIPT start
  1. 禁用systemd的兼容模式:

    SYSTEMCTL_SKIP_REDIRECT=true
    

此变量的名称可能会有所不同。你的初始化脚本可能包含类似以下内容的内容

    . /etc/sysconfig/functions

该文件将检查上述环境变量。(Suse 与基于 RedHat 的同类产品略有不同,因此可能有所不同)。

综合以上所有内容:

env -i PATH=/usr/sbin:/sbin:/usr/bin:/bin SYSTEMCTL_SKIP_REDIRECT=true  \
bash -x /etc/init.d/SCRIPT start

最后,由于输出内容非常庞大,因此请附加以下内容:

2>&1 | less -r +F

程序less将缓冲输出,以便您向后滚动整个历史记录。点击CTRL-C退出“跟随”模式,然后可以向后滚动,等等。

答案3

很可能 /etc/init.d/script 中有一个相对路径,它与 /etc/init.d/ 之外无关。您可以将脚本的内容放在这里(除非它真的很大)。

确保发送给应用程序的任何参数都不包含相对路径,因为应用程序的工作目录是启动它的目录。

相关内容