OpenHarmony应用层调用Shell指令指南
·
OpenHarmony应用层调用Shell指令指南
文档概述
说明:
1.文章由移远通信技术股份有限公司提供
2.以下内容包含了个人理解,仅供参考,如有不合理处,请联系笔者修改18770704023(微信同号)
目录
前言与背景
在OpenHarmony应用开发过程中,开发者经常会遇到系统API无法直接实现某些功能,但通过Shell命令可以实现的场景。本文档旨在提供几种在应用层调用Shell命令的方法,帮助开发者解决这类问题。
开发环境
- 系统版本:OpenHarmony 5.0.3
- 开发语言:ArkTS (ETS)、C++
- 编译环境:Ubuntu 20.04.6 LTS
- 涉及模块:ArkUI、Native C++
调用方法
方法一:使用C/C++标准库函数system()
实现步骤
-
创建Native C++工程

-
在napi_init.cpp文件中添加实现
#include <cstdlib>
static napi_value ExecuteShell(napi_env env, napi_callback_info info)
{
size_t argc = 1;
napi_value args[1] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
if (argc < 1) {
napi_value result;
napi_create_int32(env, -1, &result);
return result;
}
size_t str_len = 0;
napi_get_value_string_utf8(env, args[0], nullptr, 0, &str_len);
char* command = new char[str_len + 1];
napi_get_value_string_utf8(env, args[0], command, str_len + 1, nullptr);
int result = system(command);
delete[] command;
napi_value ret;
napi_create_int32(env, result, &ret);
return ret;
}
- 在ArkTS中调用
// 示例:调用bootanimation指令
let result: number = testNapi.executeShell('/system/bin/bootanimation');
// 其他可调用的命令示例:reboot等
特点
- 优点:实现简单,适用于不需要获取命令输出的场景
- 缺点:无法获取命令执行的输出信息,仅返回执行状态码
注意:要在build-profile.json5文件里对abiFilters进行配置,不然调用接口的时候应用会闪退并报错
方法二:使用C/C++标准库函数popen()
实现步骤
- 在napi_init.cpp文件中添加实现
#include <cstdio>
#include <string>
static napi_value ExecuteShell2(napi_env env, napi_callback_info info)
{
size_t argc = 1;
napi_value args[1] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
if (argc < 1) {
napi_value result;
napi_create_string_utf8(env, "Error: No command provided", NAPI_AUTO_LENGTH, &result);
return result;
}
size_t str_len = 0;
napi_get_value_string_utf8(env, args[0], nullptr, 0, &str_len);
char* command = new char[str_len + 1];
napi_get_value_string_utf8(env, args[0], command, str_len + 1, nullptr);
// 使用popen捕获命令输出
FILE* pipe = popen(command, "r");
if (!pipe) {
delete[] command;
napi_value result;
napi_create_string_utf8(env, "Error: Failed to execute command", NAPI_AUTO_LENGTH, &result);
return result;
}
char buffer[128];
std::string output = "";
while (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
output += buffer;
}
pclose(pipe);
delete[] command;
napi_value ret;
napi_create_string_utf8(env, output.c_str(), NAPI_AUTO_LENGTH, &ret);
return ret;
}
- 在ArkTS中调用
// 示例:获取当前日期时间
let dateResult: string = testNapi.executeShell2('/system/bin/date');
// 示例:列出目录内容
let lsResult: string = testNapi.executeShell2('/system/bin/ls');
// 示例:获取当前工作目录
let pwdResult: string = testNapi.executeShell2('pwd');
特点
- 优点:可以获取命令执行的输出信息,适用于需要处理命令结果的场景
- 缺点:实现相对复杂,需要处理文件流
方法三:通过系统属性触发指令
实现步骤
- 创建配置文件
- 创建
amixer_commands.cfg文件 - 通过build.gn内置到
system/etc/init目录
- 创建
{
"jobs" : [
{
"name" : "param:sys.amixer.commands=0",
"condition" : "sys.amixer.commands=0",
"cmds" : [
"start execute_amixer_command0"
]
}
],
"services" : [{
"name" : "execute_amixer_command0",
"start-mode" : "condition",
"path": [
"/system/bin/sh",
"-c",
"amixer cset name='VBC DAC0 DG Set' 0 0"
],
"disabled" : 1,
"sandbox" : 0,
"uid" : "root",
"gid" : ["shell"],
"once" : 1,
"secon" : "u:r:su:s0"
}]
}
- 在ArkTS中调用
import systemParameterEnhance from '@ohos.systemParameterEnhance';
// 设置系统属性触发指令
systemParameterEnhance.setSync("sys.amixer.commands", "0");
- 添加白名单
- 在
vendor/产品名/high_privilege_process_list.json中添加以下内容:
- 在
{
"name": "execute_amixer_command0",
"uid": "root",
"gid": "root"
}
特点
- 优点:可以以root权限执行命令,适用于需要高权限的操作
- 缺点:需要修改系统配置,适用于系统级应用开发
注意事项
-
权限问题:
- 应用层调用Shell命令可能受到权限限制
- 某些命令需要特定权限才能执行
-
安全风险:
- 执行Shell命令存在安全风险,尤其是当命令参数来自用户输入时
- 建议对输入参数进行严格验证
-
性能考虑:
- 频繁执行Shell命令可能影响应用性能
- 建议合理控制命令执行频率
-
错误处理:
- 应妥善处理命令执行失败的情况
- 对于popen方法,要确保正确关闭文件流
-
系统差异:
- 不同OpenHarmony版本可能存在差异
- 请根据实际系统版本调整实现
总结
本文介绍了三种在OpenHarmony应用层调用Shell命令的方法:
- system()函数:适用于简单执行命令且不需要获取输出的场景
- popen()函数:适用于需要获取命令输出的场景
- 系统属性触发:适用于需要高权限执行命令的场景
开发者可以根据具体需求选择合适的方法。在使用过程中,请注意权限管理、安全防护和错误处理,确保应用的稳定性和安全性。
附件有笔者的测试用例源码供大家参考。
更多推荐

所有评论(0)