从 bash 进行可移植的守护进程管理(sysvinit/upstart/systemd)

从 bash 进行可移植的守护进程管理(sysvinit/upstart/systemd)

我有一个小的 shell 脚本需要停止服务。这需要在 ubuntu (14.04)、debian 和 Arch 上运行。现在我所做的类似于

   案例 $(cat /etc/issue)
     *Ubuntu*)
       服务命令
     *Debian*)
       /etc/init.d/servicename 命令
     *拱*)
       systemctl 服务命令
   埃萨克

有没有更好的方法可以做到这一点?

答案1

我会说不要看当前的发行版确定使用哪个 init 系统来管理守护进程:

  • 确定发行版有点模糊(如 Dennis 的回答中所述)
  • 在发行版的不同版本之间,所使用的 init 系统会发生变化(正如 Michael Hampton 所指出的,各大发行版都倾向于使用 systemd;Ubuntu 目前是唯一一个坚持使用 systemd 的大牌发行版,他们计划在 2016 年之前完成转换)。
  • 可以在单个安装中将 init 系统从默认值更改为其他系统(从今年 10 月的 14.10 Utopic Unicorn 开始,一些 Ubuntu 安装可以选择提前切换到 systemd)。

虽然这并非万无一失(一个系统可能会选择同时安装多个 init 系统),但我的做法是寻找工具本身的存在

if command -v systemctl >/dev/null; then
  # assume systemd
  systemctl $command $servicename
elif command -v initctl >/dev/null; then
  # assume upstart
  initctl $command $servicename
elif command -v service >/dev/null; then
  # assume old Debian `service` utility
  service $servicename $command

# ... elif cases for any other utils you'd want to check for ...

else
  # assume bare init.d scripts
  /etc/init.d/$servicename $command
fi

对类似问题的回答描述了一些可用于确定当前正在使用的 init 系统的进一步启发式方法,适用于不够准确的情况。

但归根结底,没有一种方法可以确实检测安装“使用”哪一个初始化系统 - 可以创建一个在每次启动时在初始化系统之间切换的设置。

答案2

我不会使用 /etc/issue,因为这个文件有时会更改,甚至可能不会提及版本。

相反,我认为你应该搜索特定于分发的文件。

就你而言:

Debian: /etc/debian_version
Ubuntu: /etc/lsb-release
Arch: /etc/arch-release

我个人会检查文件是否存在,并根据该文件进行“区分大小写”

请参阅此处查看其他一些分发文件

linuxmafia.com

答案3

如果你因为其他原因而拥有它,因素有一个operatingsystem事实可以满足您的要求。

答案4

Ubuntu 和 Debian 都有服务实用程序。可用于service servicname start|stop除 Arch 之外的所有系统。

相关内容