我已成功使用popen()
从我的C程序中运行命令。据我了解,它在幕后使用了fork()
和exec()
(或这些的变体)。这很好用:
FILE *fd = popen("xterm", "r");
pclose(fd);
...将如预期的那样打开一个新的xterm窗口。
现在,我正在尝试使用
posix_spawn()
达到相同的目的,我知道这可能对资源更友好,尤其是如果我们不打算与新的子进程进行通信时,尤其如此:/* p.we_wordv contains the argv, index 0 holds the actual command */
pid_t pid;
posix_spawnp(&pid, p.we_wordv[0], NULL, NULL, p.we_wordv, NULL);
...但这对于
xterm
作为命令,在父项的输出中产生以下内容:xterm: Xt error: Can't open display:
xterm: DISPLAY is not set
尝试启动其他进程将产生其他错误消息,无提示地失败,或者在某些情况下(例如
ls
)按预期工作。这使我很难真正看到一种模式。您能否指出是什么导致第二种方法的行为不同于第一种?
最佳答案
消息DISPLAY is not set
告诉您xterm
找不到DISPLAY
环境变量。所有图形输出程序都使用此环境变量来连接到屏幕。
由于环境为空(它是NULL
函数调用中的最后一个posix_spawnp
),因此未找到变量。似乎popen
重用了当前进程的环境,因此它没有这个问题。
您可能想要传递仅包含所需内容的手动创建的环境,或者仅传递过程所具有的任何环境。后者更灵活(xterm
将从您的进程继承各种配置设置,而这些配置设置则从您的Shell继承),但是可能存在安全风险。
要访问您的流程环境,请使用 environ
全局变量或更改您的main
函数以接收其他参数:
int main(int argc, char *argv[], char *envp[])
{
...
posix_spawnp(&pid, p.we_wordv[0], NULL, NULL, p.we_wordv, envp);
}
关于c - 为什么posix_spawn()在popen()工作的地方失败?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48876134/