智能路由器开发之创建一个procd init脚本示例

news/2024/2/29 3:41:00

openwrt

智能路由器开发之创建一个procd init脚本示例

Procd init脚本默认提供了许多好用的功能,例如重启策略和能够从UCI系统中存储和读取配置。

设置

举个例子,假设我们想创建一个作为服务的Shell脚本,并且这个服务可以通过消息和超时时间进行配置,以便提醒我们时不时地离开座位休息一下。我们的服务名称将为"myservice",它依赖于以下脚本。

#!/bin/sh#these if statements will check input and place default values if no input is given
#they will also check if input is a number so you can call 
#this script with just a time and it will still work correctlyif [ "$1" = '' ]; thenname="You"
elseif echo "$1" | egrep -q '^[0-9]+$'; thenname="You"elsename="$1"fi
fiif [ "$2" = '' ]; thenevery="5"
elseevery="$2"
fiif echo "$1" | egrep -q '^[0-9]+$'; thenevery="$1"
fi#endless loop, will print the message every X seconds as indicated in the $every variablewhile [ 1 ]; do echo "Hey, $name, it's time to get up"sleep $every
doneexit 0

将脚本放置在 /var/myscript.sh下,并在OpenWrt上运行测试

$ /bin/sh /var/myscript.sh "Name Surname"

openwrt web

创建一个基本的procd脚本

既然我们有一个可用的脚本,我们可以将其转化为一个服务。在"/etc/init.d/myservice"路径下创建一个文件,并将以下内容添加到文件中。

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

首先,它包含了一个服务所需的常用的"/etc/rc.common"文件,该文件定义了几个函数,用于管理服务的生命周期,它支持旧式的init脚本和procd脚本。为了告诉系统我们要使用新的样式,我们设置了USE_PROCD标志。

START选项基本上告诉系统在OpenWrt启动和关闭期间,服务应该何时启动和停止。

目前这个init脚本并不是很有用,但它展示了我们将进一步开发脚本所需的基本构建模块。

启用服务

告诉OpenWrt我们有一个新的服务将要运行

/etc/init.d/myservice enable

这将在目录"/etc/rc.d/“中为我们安装一个符号链接,名称为"S90myservice”,它指向位于"/etc/init.d/“中的相应服务脚本。OpenWrt将根据”/etc/rc.d/"中S*脚本的顺序启动服务。要查看顺序,您可以简单地运行以下命令:

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

能够影响服务启动顺序非常有用,如果我们的服务依赖于网络,我们需要确保START顺序的索引至少比网络服务的START顺序大1。

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

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

您总是需要在脚本中定义一个STARTSTOP序列(您也可以同时定义两者)。如果您定义了STOP序列,您还需要在初始化脚本中定义一个stop_service()处理程序。该处理程序通常负责清理服务资源或在服务重新启动时需要的数据持久化。测试服务

最后,让我们测试一下我们的服务。打开第二个终端连接到OpenWrt设备,并运行以下命令:

$ logread -f

这将在设备上跟踪系统日志。然后启用(如果尚未启用)并启动服务。

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

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

#!/bin/sh /etc/rc.commonUSE_PROCD=1START=95
STOP=01start_service() {procd_open_instanceprocd_set_param command /bin/sh "/var/myscript.sh"procd_set_param stdout 1procd_set_param stderr 1procd_close_instance
}

重启服务后,使用logread -f命令,我们能看到下面的log输出:

$ 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
...

像上面那样设置一个简单的procd脚本已经给我们带来了一些优势:

  • 共享的API来管理服务
  • 该服务将在每次启动时自动启动
    openwrt web

服务配置

是时候变得更加个性化了,为此我们将使用OpenWrt的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

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

加载服务配置项

我们已经可以通过将参数传递给节点脚本来传递配置。我们需要做的唯一事情是加载与配置匹配的服务,将我们需要的选项的值存储到某些变量中,并将它们传递给启动脚本的命令。

#!/bin/sh /etc/rc.commonUSE_PROCD=1START=95
STOP=01CONFIGURATION=myservicestart_service() {# Reading configconfig_load "${CONFIGURATION}"local namelocal everyconfig_get name hello nameconfig_get every hello everyprocd_open_instance# pass config to script on startprocd_set_param command /bin/sh "/var/myscript.sh" "$name" "$every"procd_set_param file /etc/config/myserviceprocd_set_param stdout 1procd_set_param stderr 1procd_close_instance
}

我们也可以通过下面的命令传递新的配置项

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

请注意,在服务脚本中,参数被引号引起来,这样我们就可以在name选项中使用空格。如果我们不这样做,每个名称部分都将被视为单独的参数。

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

#//
procd_set_param file /etc/config/myservice
#//

有了这行代码,我们只需要在配置发生更改时重新启动服务。

$ /etc/init.d/myservice reload

openwrt acc

高级选项

还有一些在procd脚本的"instance block"中可以配置的选项,这些选项可能会很有用。我在这里列举了一些,但并不意味着包含了所有内容。

  • respawn
    在某些情况下,当您的服务意外停止时,可以自动重新启动它。
procd_set_param respawn \${respawn_threshold:-3600} \${respawn_timeout:-5} ${respawn_retry:-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设备上的系统范围内的ulimit设置,您可以运行以下命令:

$ 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 

默认情况下,OpenWrt只有一个’root’用户或’nobody’作为进程所有者。
您可以按照通常的Linux方式添加用户,请参阅在OpenWrt中创建非特权用户。如果您正在创建一个实际的软件包,您可以使用buildpackage定义,在软件包安装时让OpenWrt生成用户。


https://www.jiucaihua.cn/news/show-4626281.html

相关文章

软件测试新人害怕不过试用期,教你几招使你安稳度过!!!

对于很多刚步入职场的新人来说,害怕自己试用期过不了,被辞退。别的行业我可能不知道该如何帮大家应对,但在测试行业我希望还是能给大家带俩一点帮助,希望大家能安稳度过试用期,并且成功入行。 保持初心,安稳…

box-shadow盒子阴影几种用法

box-shadow盒子阴影 语法: 外阴影:box-shadow: X轴 Y轴 Rpx color; 属性说明(顺序依次对应): 阴影的X轴(可以使用负值) 阴影的Y轴(可以使用负值) 阴影模糊值(大小) 阴影的颜色 内阴…

Vulkan Tutorial 8 深度缓冲

目录 26 三维几何图形 深度图像和视图 27 显式转换深度图像 渲染通道 帧缓冲区 清除值 深度和模版状态 处理窗口调整大小 26 三维几何图形 到目前为止,我们所处理的几何体是投射到三维的,但它仍然是完全平面的。在这一章中,我们要给位…

股票买卖篇(II,III,IV)--基础,详细!状态机简单应用

目录 股票买卖II 本题思路 关于异常值的解释 代码 股票买卖III 本题思路 (包括对交易过程的理解,需认真理解) 代码 股票买卖 IV 本题思路 代码 股票买卖II 输入样例 6 7 1 5 3 6 4 输出样例 7 输入样例 5 1 2 3 4 5 输出样例 4 本题思路 该题是最…

linux基础知识学习记录

这里写自定义目录标题 一、 计算机基础知识二 、 Linux操作系统的介绍三、 Linux的安装四、Linux命令使用汇总 一、 计算机基础知识 计算机组成:计算机主要硬件和软件2部分组成。计算机软硬件的概念:硬件是可以看得见的物理实体,软件是运行在…

Cubase12没有声音解决办法(Windows 11专用)

本文章由CSDN 不想加班呀 原创,转载请注明出处。 作者首页:不想加班呀的博客_CSDN博客-Python爬虫,电脑小知识,程序员剪视频领域博主 目录 前言 解决办法 第一步(进入系统硬件和声音设置界面) 第二步(在声音设置中…

(学习日记)2023.04.27

写在前面: 由于时间的不足与学习的碎片化,写博客变得有些奢侈。 但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。 既然如此 不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录&a…

柔性车间作业调度

1柔性车间作业调度 n n n个工件 { J 1 , J 2 , ⋯ , J n } \{J_1,J_2,\cdots,J_n\} {J1​,J2​,⋯,Jn​}要在 m m m台机器 { M 1 , M 2 , ⋯ , M m } \{M_1,M_2,\cdots,M_m\} {M1​,M2​,⋯,Mm​}上加工。每个工件包含一道或多道工序,工序顺序是预先确定的&#xf…

微信小程序获取手机号码 phonenumber.getPhoneNumber 提示47001错误

微信小程序获取手机号码 phonenumber.getPhoneNumber 提示47001错误 微信小程序获取客户端手机号码,踩的坑。如下提示: {"errcode":47001,"errmsg":"data format error hint: [6kMDxSDNRa-hAwqia] rid: 6308d1b5-69935bc9-1d9…

大数据:spark环境搭建,local模式,standalone模式,zookeeper standby,yarn模式

大数据:spark环境搭建,local模式 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 测开的话,你就得学数据库,sql,or…