树莓派CPU频率调整问题:sudo su后无法执行命令修改scaling_setspeed
问题
我正在开发一款树莓派程序,该程序持续监控可用CPU核心的利用率,并计算CPU应运行的最优频率。但在执行实际修改CPU频率的功能时遇到了问题。
我当前的代码片段如下:
system("cd ~; cd /sys/devices/system/cpu/cpufreq/policy0; sudo su;")
然而,我无法找到方法在执行上述命令后继续执行最后一条命令:
echo //some_frequency > scaling_setspeed
我尝试了以下几种方式:
- 拼接命令字符串:
int freq = //some number char buf[BIFSIZ] snprintf(buf, sizeof(buf), "cd ~; cd /sys/devices/system/cpu/cpufreq/policy0; sudo su; echo %d > scaling_setspeed", freq); system(buf)
- 分开执行
system和cout输出:
system("cd ~; cd /sys/devices/system/cpu/cpufreq/policy0; sudo su;") cout << "echo " << freq << " > scaling_setspeed" << endl;
- 分开执行
system和printf输出:
system("cd ~; cd /sys/devices/system/cpu/cpufreq/policy0; sudo su;") printf("echo %d > scaling_setspeed");
这些方法均未奏效,希望能得到解决方法。
解决方案
核心问题是**sudo su会启动独立的root shell会话,后续命令无法在这个会话中执行**——system()调用的每个命令(或分号分隔的命令序列)都运行在同一个初始子shell里,sudo su之后的命令不会被新启动的root shell接收。
以下是几种可行的解决方式:
方法1:直接用sudo执行写入命令(最简)
无需切换root shell,直接给写入操作加上sudo权限,同时用tee绕过重定向的权限限制:
int freq = 1200000; // 替换为你的计算值 char buf[BIFSIZ]; snprintf(buf, sizeof(buf), "echo %d | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed", freq); system(buf);
tee命令能通过sudo获取root权限,直接写入目标文件,避免了普通用户重定向时的权限不足问题。
方法2:用sudo -c执行完整命令序列
如果需要先切换目录再操作,可通过sudo -c将整个命令序列交给root shell执行:
int freq = 1200000; char buf[BIFSIZ]; snprintf(buf, sizeof(buf), "sudo -c 'cd /sys/devices/system/cpu/cpufreq/policy0 && echo %d > scaling_setspeed'", freq); system(buf);
用&&代替分号,确保目录切换成功后才执行写入操作,整个命令序列被单引号包裹,作为sudo -c的参数在root权限下运行。
方法3:直接用程序系统调用写入(推荐)
避免依赖system()调用shell,直接用C++文件操作或系统调用写入,效率更高且更可控:
#include <fstream> #include <cstdio> // ... int freq = 1200000; std::ofstream freq_file("/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed"); if (freq_file.is_open()) { freq_file << freq << std::endl; freq_file.close(); } else { perror("Failed to open scaling_setspeed"); // 提示用户需要用sudo运行程序 }
注意:运行该程序时必须加上sudo权限(如sudo ./your_program),因为scaling_setspeed文件仅允许root用户写入。
内容的提问来源于stack exchange,提问作者Jared Kinneer
相关产品推荐
相关产品推荐

