解析proc / pid / cmdline以获取函数参数

时间:2009-09-10 17:32:27

标签: c++ linux procfs

我正在尝试使用cmdline中的数据提取调用应用程序的参数。

如果我启动这样的应用程序实例:

  

myapp 1 2

然后捕捉myapp的cmdline我会看到类似myapp12的内容。

我需要提取这些值,并使用这段代码来实现它


pid_t proc_id = getpid();

sprintf(buf,"/proc/%i/cmdline",proc_id);

FILE * pFile;
pFile = fopen (buf,"r");
if (pFile!=NULL)
{
    fread(buf,100,100,pFile);
    cout << "PID " << proc_id << endl;
    string str = buf;
    cout << buf << endl;
    size_t found=str.find_last_of("/\\");
    cout << " file: " << str.substr(found+1) << endl;

    fclose (pFile);
}

但我得到的只是应用名称而没有参数......


更新来自答案:

好吧,我现在的问题似乎是如何读取cmdline文件而不停在第一个NULL字符...

fopen(cmdline, "rb")

没有做任何其他事情......

2 个答案:

答案 0 :(得分:9)

/usr/bin/strings /proc/1337/cmdline通常为我做这份工作。

答案 1 :(得分:7)

所有命令行参数(作为argv[]数组的内容)实际上是/proc/XXX/cmdline中以空值分隔的字符串。

abatkin@penguin:~> hexdump -C /proc/28460/cmdline
00000000  70 65 72 6c 00 2d 65 00  31 20 77 68 69 6c 65 20  |perl.-e.1 while |
00000010  74 72 75 65 00                                    |true.|

这解释了为什么当您cat'ed cmdline时,他们全都“卡在一起”(cat忽略了无效的NULL字符)以及为什么cout(numRead - 2)之后停止了第一个命令行参数(进程名称),因为它认为进程名称是以空字符结尾的字符串,并且在此时停止查找更多字符。

处理命令行参数

要处理命令行参数,您有几个选项。如果您只想将整个命令行作为一个巨大的字符串,则从0循环到numRead(其中(curByte == 0)是读取的字符数)并用空格替换任何NULL字节(numRead - 1)。然后确保将最后一个字符设置为NULL字节(如果由于固定大小的缓冲区而导致事物被截断)。

如果你想要一个包含所有参数的数组,你需要更有创意。一种选择是从0循环到char*,并且可以找到所有的NULL字节。然后分配一个长度为char*的数组。然后循环返回命令行,将每个字符串的开头(即数组中的第一个字节,加上NULL字节后的每个字节)设置为{{1}}数组的连续元素。

只要知道,因为您读取固定大小的缓冲区,超出该缓冲区的任何内容都将被截断。所以请记住,无论你做什么,你可能需要手动确保最后一个字符串的结尾最终被NULL终止,否则大多数字符串处理函数将不知道字符串结束的位置,并将继续永远。