C从/ proc

时间:2018-02-14 02:37:52

标签: c file scanf pid

我正在尝试从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'吗? (注意:我不需要提取任何其他字符串)。

谢谢!

2 个答案:

答案 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)

  1. /proc/PID/cmdline包含用于执行程序的命令行(除非程序本身修改)。它不包含可执行文件的路径;它只包含用于执行它的路径。

    例如,如果您执行foo bar baz,其/proc/PID/cmdline将包含foo\0bar\0baz\0

    您可以使用例如getdelim()'\0'作为分隔符来读取可执行文件的路径。

  2. 要获取可执行文件的实际路径,请检查/proc/PID/exe符号链接。它总是指向可执行文件。

    要阅读符号链接,您可以使用C库提供的POSIX.1 readlink()函数。

    我有一个示例实现in this answer

    在Linux中,存在内核“错误”:如果文件系统层次结构中的可执行文件非常深,则readlink()伪符号链接上的/proc/PID/exe调用将失败并显示ENAMETOOLONG错误点。

  3. 也可以从/proc/PID/stat中提取可执行文件的路径。

    可执行文件的名称位于该伪文件中的第一个(和最后一个)之间。

    您可以使用getline()来读取整行(实际上是整个伪文本,因为它最后只包含换行符),strchr()可以找到其中的第一个(,以及strrchr()找到最后一个)

  4. 如果您想尝试有趣/讨厌的可执行文件名称,只需运行例如。

    ln -s /bin/cat $'foo)\nbar\n('
    $'./foo)\nbar\n(' /proc/self/stat
    rm $'foo)\nbar\n('
    
    在Bash中

    ,检查/proc/self/stat的内容。