OpenWrt - rpcd

本文介绍如何利用 OpenWrt 的 rpcd 服务通过 ubus 接口暴露 shell 脚本功能。通过编写简单的 shell 脚本并放置在指定目录下,即可实现自定义的 ubus 函数。这些函数可用于远程调用,为设备提供丰富的交互能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://wiki.openwrt.org/doc/techref/rpcd

rpcd (OpenWrt ubus RPC backend server)//Openwrt ubus RPC后端服务

The code is published under ISC and can be found via git at

plugin executables //可执行插件

It is possible to expose shell script functionality over ubus by using rpcd plugin executables functionality. Executables stored in /usr/libexec/rpcd/ directory will be runned by rpcd. Lets look at the following example:

通过使用rpcd的可执行插件功能,可以通过ubus曝光shell描述符功能。可执行文件保存在/usr/libexec/rpcd目录下,rpcd将运行他么。让我们看下面的例子:

$ cat << EOF > /usr/libexec/rpcd/foo
#!/bin/sh

case "$1" in
    list)
        echo '{ "bar": { "arg1": true, "arg2": 32, "arg3": "str" }, "toto": { } }'
    ;;
    call)
        case "$2" in
            bar)
                # read the arguments
                read input;

                # optionally log the call
                logger -t "foo" "call" "$2" "$input"

                # return json object or an array
                echo '{ "hello": "world" }'
            ;;
            toto)
                # return json object or an array
                echo '[ "item1", "item2", "item3" ]'
            ;;
        esac
    ;;
esac
EOF
$ chmod +x /usr/libexec/rpcd/foo

This will create new ubus functions which then can be used (after restarting rpcd):

这将创建新的ubus函数,然后可以运行它们(重新启动rpcd):

$ ubus list -v
...
'foo' @686f0592
    "bar":{"arg1":"Boolean","arg2":"Integer","arg3":"String"}
    "toto":{}
...
$ ubus call -S foo bar '{"arg1": true }'
{{"hello":"world"}}
$ ubus call -S foo toto
{["item1","item2","item3"]}

On startup rpcd will call all executables in /usr/libexec/rpcd/ with argv[1] set to “list”. For a plugin, which responds with a valid list of methods and signatures, ubus method with appropriate arguments will be created. When a method provided by the plugin is about to be invoked, rpcd calls the binary with argv[1] set to “call” and argv[2] set to the invoked method name. The actual data is then sent by the ubus client via stdin.

rpcd启动将调用所有在/usr/libexec/rpcd下所有可执行程序,使用argv[1]设置一个’list’。对于一个插件,相应一个有效的方法列表和标签,ubus方法用一个创建的合适的参数。当一个插件提供的方法被调用,rpcd用二进制,用argv[1]设置”call”,argv[2]设置调用方法名。激活的数据被ubus客户机发送到stdin。

The method signature is a simple object containing key:value pairs. The argument type is inferred from the value. If the value is a string (regardless of the contents) it is registered as string, if the value is a bool true or false, its registered as bool, if the value is an integer, it is registered as either int8, int16, int32 or int64 depending on the value (“foo”: 16 will be INT16, “foo”: 64 will be INT64, “foo”: 8 will be INT8 and everything else will be INT32).

方法标签是一个简单的对象,包含键:value pairs。参数类型由值推测。如果值是一个字符串(不理会内容),它的寄存器作为字符串,如果值是一个bool true/false,它的寄存器是bool,如果值是一个integer,它的寄存器既可以是int8,int16,int32,也可以是int64,依赖值(“foo”:16是INT16,“foo”:64是INT64,“foo”:8是INT8其它的是INT32)。

It is enough to issue ‘/etc/init.d/rpcd reload’ to make it pick up new plugin executables, that way one does not lose active sessions.

执行/etc/init.d/rpcd reload可以开始执行新的可执行插件,这个方法不会丢掉激活的部分。

<think>嗯,用户需要了解OpenWrt下如何创建IPK包。根据引用内容,用户提供了几个相关参考,但核心需求是创建IPK包的完整流程。用户可能正在开发OpenWrt应用或移植软件到路由器,需要标准化打包方法。 从引用[1]和[2]看,关键步骤是搭建SDK环境、创建项目结构、编写Makefile。引用[3]补充了安装后脚本的处理,引用[4]则涉及luci界面的资源路径。需要整合这些信息,但要注意用户可能不需要luci部分(除非特别说明)。 考虑分四步说明:环境准备(强调SDK获取)、项目创建(演示helloworld示例)、Makefile编写(重点解释变量含义)、编译安装。用户可能是开发者,所以技术细节要准确,比如$(eval $(call BuildPackage,helloworld))这种OpenWrt特有语法必须解释清楚。 需要提醒用户注意:1) SDK版本匹配固件 2) 依赖声明的重要性 3) 安装后脚本的实际应用场景。用户可能遇到的坑是:交叉编译工具链缺失、文件权限错误、或忘记重载服务(如luci应用)。 最后生成的问题要覆盖延伸需求:测试方法(如QEMU模拟)、依赖管理(如opkg depends)、自定义脚本(引用[3]的uci-defaults示例)和luci集成(虽然用户没提但常见)。避免问题过于基础(如"什么是IPK包"),聚焦在打包的上下游环节。</think>以下是基于OpenWrt创建IPK软件包的完整教程,整合了关键步骤和最佳实践: --- ### **一、环境准备** 1. **获取OpenWrt SDK** - 从官方下载与固件版本匹配的SDK(如`openwrt-sdk-xx.xx.xx.tar.xz`) - 解压并进入目录: ```bash tar -xvf openwrt-sdk-xx.xx.xx.tar.xz cd openwrt-sdk-xx.xx.xx ``` 2. **安装编译依赖** ```bash sudo apt update sudo apt install build-essential libncurses5-dev unzip ``` --- ### **二、创建项目结构** 以`helloworld`为例: ``` helloworld/ ├── Makefile # 包控制文件 └── src/ ├── helloworld.c # 源代码 └── Makefile # 编译规则 ``` --- ### **三、关键文件配置** 1. **主Makefile** (`helloworld/Makefile`) ```makefile include $(TOPDIR)/rules.mk PKG_NAME:=helloworld PKG_VERSION:=1.0 PKG_RELEASE:=1 include $(INCLUDE_DIR)/package.mk define Package/helloworld SECTION:=utils CATEGORY:=Utilities TITLE:=HelloWorld Demo endef define Package/helloworld/description A simple "Hello World" application for OpenWrt. endef define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ endef define Package/helloworld/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/usr/bin/ endef $(eval $(call BuildPackage,helloworld)) ``` 2. **源代码Makefile** (`helloworld/src/Makefile`) ```makefile CC = gcc CFLAGS = -Wall all: helloworld helloworld: helloworld.o $(CC) $(CFLAGS) -o $@ $^ clean: rm -f *.o helloworld ``` --- ### **四、编译生成IPK** 1. **更新Feeds并编译** ```bash ./scripts/feeds update -a ./scripts/feeds install -a make package/helloworld/compile V=s ``` 2. **获取IPK包** 生成路径: `bin/packages/<架构>/base/helloworld_1.0-1_<架构>.ipk` --- ### **五、安装与测试** 1. **上传到设备** ```bash scp helloworld_*.ipk root@192.168.1.1:/tmp/ ``` 2. **安装并运行** ```bash opkg install /tmp/helloworld_*.ipk helloworld # 输出 "Hello World!" ``` --- ### **六、高级功能** 1. **安装后脚本**(引用[3]) 创建`files/etc/uci-defaults/99-helloworld`: ```bash #!/bin/sh /etc/init.d/rpcd reload # 重载服务使Luci生效 exit 0 ``` 2. **添加配置文件** ```makefile define Package/helloworld/conffiles /etc/config/helloworld endef ``` --- ### **常见问题解决** - **编译错误**:检查SDK版本与设备架构是否匹配 - **菜单不显示**:确保`/etc/init.d/rpcd reload`执行(引用[3]) - **依赖缺失**:在Makefile中添加`DEPENDS:=+libpthread` > 引用验证:SDK生成步骤[^1],项目结构规范[^2],安装后脚本[^3],路径规范[^4] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值