Hublog随手记录一些东西

Chroot无法使用systemd解决办法

参考链接:unix - Start a systemd service inside chroot from a non systemd based rootfs - Super User

Github:https://github.com/smaknsk/servicectl

简介

在使用 systemctl 管理服务的时候,一般会提示。

1
2
sudo systemctl start nginx
Running in chroot, ignoring request.

外部系统要求:

  • 使用systemd,http://0pointer.de/blog/projects/changing-roots。
  • 使用 SysVinit 脚本,可以直接使用servicectl。

内部系统要求:

  • chroot系统内部必须安装systemd。

安装

通过包安装

ArchLinux - https://aur.archlinux.org/packages/servicectl/

手动安装

1
2
3
4
wget https://github.com/smaknsk/servicectl/archive/1.0.tar.gz
tar -xf 1.0.tar.gz -C /usr/local/lib/
ln -s /usr/local/lib/servicectl-1.0/servicectl /usr/local/bin/servicectl
ln -s /usr/local/lib/servicectl-1.0/serviced /usr/local/bin/serviced

使用方法

servicectl

1
sudo servicectl [action] [service]

这个命令只是从/usr/lib/systemd/system/${service}.service文件执行指定的${action},如果${action}是enable或者disable,servicectl会给${service}.service创建或删除符号连接,以供serviced使用。

参数:

  • action - 可以是{start, stop, restart, reload, enable, disable}
  • service - /usr/lib/systemd/system/目录中的文件名

serviced

1
sudo serviced action

这个命令为所有启用的服务执行${action}动作。

参数:

  • action - 默认为 start,可以为 {start, stop, restart, reload, disable}

示例

例如我在使用的Debian系统。

1
2
3
4
5
6
# chroot内部
sudo servicectl enable nginx php-fpm

# chroot外部 
# init初始化,运行所有启用的服务
sudo chroot /path/to/chroot serviced

可能遇到的问题:

1
2
/usr/local/bin/servicectl: 16: [: -ne: unexpected operator
/usr/local/bin/servicectl: 23: Syntax error: "(" unexpected

这是由于脚本解释器的原因导致的,查看/usr/local/bin/servicectl文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
head /usr/local/bin/servicectl

#!/bin/sh
# Control services for system based on Systemd inside chroot and SysVinit outside chroot
# https://github.com/smaknsk/servicectl
#

# Pach systemd services file
SYSTEMD_UNITS_PATH="/usr/lib/systemd/system/"

# Path locate this script
DIR=$(dirname $(readlink -f $0))

可以看到使用的是sh这个解释程序,我们再查看下sh这个命令。

1
2
ll /bin/sh
lrwxrwxrwx. 1 root root 4  1月 25 11:59 /bin/sh -> dash

Debian的脚本解释器默认为dash,所以使用sh作为解释器执行的的脚本,会被dash来执行,所以导致有些字符和变量不兼容。

如果修改代码可能比较复杂,改动量比较打,我们用最简单的解决方法,更换解释器。

编辑/usr/local/bin/servicectl文件,将解释器更换为:#!/usr/bin/env bash。同理/usr/local/bin/serviced文件也需要改一下。

0%