系统的C函数(" $ BASHPID")不起作用

时间:2014-07-05 06:56:46

标签: c linux process

我在Ubuntu 12.04中使用system()函数用C编写了一个简单的程序,如下所示:

#include <stdio.h>
#include <unistd.h>

int main()
{
    printf("getpid() = %d\n", getpid());
    printf("getppid() = %d\n", getppid());
    printf("cmd process ID:\n");

    system("echo $BASHPID");
    return 0;
}

并使用终端中的gcc运行它,结果如下。

$ gcc -o exmpl_bashpid exmpl_bashpid.c
$ ./exmpl_bashpid 
getpid() = 2892
getppid() = 2060
cmd process ID:

$

我的问题是,功能系统(&#34; echo $ BASHPID&#34;)不会给出任何东西。当我尝试使用一些常见的命令,比如它在运行可执行文件时在终端中给出的日期。只有上述情况才能给出正确的结果。可能的解释是什么?我最不熟悉C编程中的Linux进程和系统调用。任何见解都将有助于我的进一步探索。感谢。

2 个答案:

答案 0 :(得分:1)

system通常会运行/bin/sh,大概不会设置$BASHPID。尝试使用:

system("/bin/bash -c 'echo $BASHPID'")

请注意,这总是只打印由system调用的 bash进程的PID,这不是很有用。看起来您正在尝试获取 bash进程的PID,这不会因为未输出父bash的BASHPID变量而导致输入

/bin/sh -c 'echo $BASHPID'
命令行中的

将演示。

答案 1 :(得分:0)

要在C程序中检索环境变量,请使用getenv(3)

因此,如果您认为您的程序是在设置BASHPID的环境中运行的(例如bash中的export -ed),请尝试:

int bashpid = 0;
char*bashpidstr = getenv("BASHPID");
if (bashpidstr && isdigit(bashpidstr[0]))
  bashpid = atoi(bashpidstr);

但是,shell通常是父进程,您可以使用getppid(2)进行查询。或者它是流程组负责人,请参阅getpgid(2)

如果您希望获得某些命令的输出,请使用popen(3),例如

int bashpid = 0;
FILE* cmd = popen("echo $BASHPID", "r");
if (cmd) { fscanf(cmd, "%d", &bashpid); pclose(cmd); }
else { perror("popen"); exit(EXIT_FAILURE); }

但这可能无法按你的意愿行事,因为popensystem /bin/sh bash echo $$可能是bash;也许你应该fflush(NULL);

此外,fork特定于popen。我的交互式(登录)shell是BASHPID,因此无法设置它。

请注意,您通常应在system execl("/bin/sh", "sh". "-c", command, (char *) 0); 等任何分叉函数之前调用zsh(例如NULL ...),以确保刷新stdio缓冲区。 / p>

附加物

如果您想知道fflush(3)是否正在创建不同的流程,请阅读其文档:

  

system()库函数使用fork(2)来创建子进程          使用execl(3)执行命令中指定的shell命令          如下:

system
     

system()在命令完成后返回。

但是,如果您将{{1}}参数传递给{{1}},则会出现一种特殊情况:

  

如果command为NULL,则system()返回指示是否为的状态          系统上有一个shell

另外,研究一些实现的源代码,例如:来自system(3)

process/system.c