procd | 最简单的procd服务脚本

配置

假设我们想要创建一个服务,该服务在服务超时时进行消息提示,定时提醒我们从办公桌起身活动下。我们的服务名称是myservice,它依赖下面的脚本:

/var/myscript.sh

#!/bin/sh

if [ "$1" = '' ]; then
    name="You"
else
    if echo "$1" | egrep -q '^[0-9]+$'; then
        name="You"
    else
        name="$1"
    fi
fi

if [ "$2" = '' ]; then
    every="5"
else
    every="$2"
fi

if echo "$1" | egrep -q '^[0-9]+$'; then
    every="$1"
fi

#endless loop, will print the message every X seconds as indicated in the $every variable

while [ 1 ]; do
    echo "Hey, $name, it's time to get up"
    sleep $every
done

exit 0

我们在 OpenWrt 上运行来测试它,脚本将在每一小时提醒你起来走动走动,喝杯茶。

$ /bin/sh /var/myscript.sh "My_Name" 3600

创建一个基本的 procd 脚本

现在我们有了一个工作脚本,我们可以用它来制作服务。在 /etc/init.d/myservice 中创建一个文件,内容如下

#!/bin/sh /etc/rc.common
USE_PROCD=1
START=95
STOP=01
start_service() {
    procd_open_instance
    procd_set_param command /bin/sh "/var/myscript.sh"
    procd_close_instance
}

第一行表示使用“/etc/rc.common”来解释脚本。
第二行内容设置 USE_PROCD 变量为 1,表示使用 procd 来管理进程

START 、STOP选项:告诉系统在 OpenWrt 的启动和关闭系统服务时的顺序。

启用服务

告诉 OpenWrt 我们需要运行一个新服务

 /etc/init.d/myservice enable

这将在目录 /etc/rc.d/ 创建一个名为 S90myservice 的符号链接,它指向我们在 /etc/init.d/ 中的myservice脚本。

OpenWrt 会按照 /etc/rc.d/ 中 S* 脚本的顺序启动服务,通过如下命令可以查看到所有自启服务。

$ ls -la /etc/rc.d/S*

相同的规则适用于可选的 STOP 参数,只是这次它定义了服务关闭的顺序。可以运行命令查看下:

$ ls -la /etc/rc.d/K*

在init脚本中需要定义START或者STOP选项,如果定义了STOP选项,你还需要在init脚本中一个stop_service()函数,在该函数中完成服务资源的清理或服务再次启动时所需数据的初始化。

最后,让我们测试一下我们的服务。打开 OpenWrt 设备的第二个 shell 并运行如下命令,它阻塞监听系统日志:

$ logread -f

然后启动服务。

$ /etc/init.d/myservice enable 
$ /etc/init.d/myservice start

大约 5 秒后,我们应该会在日志中看到消息重复出现,但实际并没有……我们仍然需要将 stdout 和 stderr 重定向到 logd,以便在系统日志中看到终端 log 输出。

#!/bin/sh /etc/rc.common

USE_PROCD=1

START=95
STOP=01

start_service() {
    procd_open_instance
    procd_set_param command /bin/sh "/var/myscript.sh"
    procd_set_param stdout 1
    procd_set_param stderr 1
    procd_close_instance
}

现在,当我们重新启动时,我们应该看到类似

$ logread -f
... ommitted ... Hey, You, it's time to get up
... ommitted ... Hey, You, it's time to get up
... ommitted ... Hey, You, it's time to get up
... ommitted ... Hey, You, it's time to get up
... ommitted ... Hey, You, it's time to get up
... ommitted ... Hey, You, it's time to get up
...

服务配置

是时候变得更加个性化了,为此我们将使用 OpenWrts UCI 配置界面。创建一个配置文件 /etc/config/myservice ,内容如下

config myservice 'hello'
	option name 'Joost'
 	option every '5'

UCI 将立即获取此信息,并且可以检查我们服务的配置,例如

$ uci show myservice 
myservice.hello=myservice 
myservice.hello.name=Joost 
myservice.hello.every='5'

也可以请求单个选项

$ uci get myservice.hello.name

我们还可以使用 UCI 更改特定配置

$ uci set myservice.hello.name=Knight
$ uci commit

现在,我们将对服务脚本进行一些更改,以便读取和使用脚本中的配置。

加载服务配置

上面我们已经将配置保存在/etc/config/myservice,下面我们将在init脚本中读取这个文件的配置信息。

#!/bin/sh /etc/rc.common

USE_PROCD=1

START=95
STOP=01

CONFIGURATION=myservice

start_service() {
    # Reading config
    config_load "${CONFIGURATION}"
    local name
    local every

    config_get name hello name
    config_get every hello every

    procd_open_instance

    # pass config to script on start
    procd_set_param command /bin/sh "/var/myscript.sh" "$name" "$every"
    procd_set_param file /etc/config/myservice
    procd_set_param stdout 1
    procd_set_param stderr 1
    procd_close_instance
}

我们可以通过运行来传递新的配置

$ uci set myservice.hello.name=Woodrow
$ uci commit

除了加载和传递配置到我们的脚本之外,我们还添加了

...
procd_set_param file /etc/config/myservice
...

有了这句代码,我们可以在配置文件发生变化时,通过如下命令重新加载服务。

$ /etc/init.d/myservice reload

高级选项

可以在 procd 脚本中配置更多选项,我将在这里列出一些,但这绝不是涵盖所有内容。

  • respawn
    当服务挂掉时,自动重启

    procd_set_param respawn \
           ${respawn_threshold:-3600} \
           ${respawn_timeout:-5}  ${respawn_retry:-5}
    

    在这个例子中,如果进程比 respawn_threshold 更早死亡,它会被认为已经崩溃,我们会重启,5 次重试后服务停止

  • pidfile
    配置pid文件的存储位置

    procd_set_param pidfile $PIDFILE
    
  • env vars
    传递给进程的环境变量

    procd_set_param env A_VAR = avalue
    
  • ulimit
    设置资源限制

    procd_set_param limits core="unlimited"
    

    要在 OpenWrt 设备上查看 ulimt 的系统范围设置,可以运行

    $ ulimit -a
    -f: file size (blocks)             unlimited
    -t: cpu time (seconds)             unlimited
    -d: data seg size (kb)             unlimited
    -s: stack size (kb)                8192
    -c: core file size (blocks)        0
    -m: resident set size (kb)         unlimited
    -l: locked memory (kb)             64
    -p: processes                      475
    -n: file descriptors               1024
    -v: address space (kb)             unlimited
    -w: locks                          unlimited
    -e: scheduling priority            0
    -r: real-time priority             0
    
  • user
    可以运行该服务的用户

     procd_set_param user nobody 
    
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值