我正在尝试从C中的/ proc / pid / cmdline获取包含PID可执行文件的路径。手册页说明:
“出现命令行参数 在此文件中,作为由空字节分隔的一组字符串 ('\ 0'),在最后一个字符串后面还有一个空字节。“
我的想法(伪代码):
int main(int argc, char** argv){
// Assume file_path has been initialized
char executable_path[1000];
FILE* file = fopen(file_path, "r");
if(f != NULL){
fscanf("%s", executable_path);
}
return 0;
}
因为我只想要这个文件中的第一个字符串(因为那是包含可执行文件的路径)而且我确定在第一个字符串后面有一个'\ 0',fscanf是否是正确的函数?它会检测第一个'\ 0'然后将整个字符串存储到executable_path数组中的第一个'\ 0'吗? (注意:我不需要提取任何其他字符串)。
谢谢!
答案 0 :(得分:2)
请不要使用fscanf
,如果命令名称中有空格,则不会使用fgets
得到全名。
您可以使用'\0'
,它将停止阅读FILE *fp = fopen("/proc/10979/cmdline", "r");
char line[1024];
fgets(line, sizeof line, fp);
puts(line);
fclose(fp);
。我现在有一个
使用pid 10979运行的进程:
/usr/bin/gvim
打印:
=SUMPRODUCT($C$4:$H$4*(COLUMN($C$4:$H$4)-COLUMN($C$4)+1<=MONTH(TODAY())*2)*(LEFT($C$3:$H$3)="A"))
答案 1 :(得分:0)
/proc/PID/cmdline
包含用于执行程序的命令行(除非程序本身修改)。它不包含可执行文件的路径;它只包含用于执行它的路径。
例如,如果您执行foo bar baz
,其/proc/PID/cmdline
将包含foo\0bar\0baz\0
。
您可以使用例如getdelim()
以'\0'
作为分隔符来读取可执行文件的路径。
要获取可执行文件的实际路径,请检查/proc/PID/exe
符号链接。它总是指向可执行文件。
要阅读符号链接,您可以使用C库提供的POSIX.1 readlink()
函数。
我有一个示例实现in this answer。
在Linux中,存在内核“错误”:如果文件系统层次结构中的可执行文件非常深,则readlink()
伪符号链接上的/proc/PID/exe
调用将失败并显示ENAMETOOLONG
错误点。
也可以从/proc/PID/stat
中提取可执行文件的路径。
可执行文件的名称位于该伪文件中的第一个(
和最后一个)
之间。
您可以使用getline()
来读取整行(实际上是整个伪文本,因为它最后只包含换行符),strchr()
可以找到其中的第一个(
,以及strrchr()
找到最后一个)
。
如果您想尝试有趣/讨厌的可执行文件名称,只需运行例如。
ln -s /bin/cat $'foo)\nbar\n('
$'./foo)\nbar\n(' /proc/self/stat
rm $'foo)\nbar\n('
在Bash中,检查/proc/self/stat
的内容。