Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中的参数中使用带shell元字符的execlp系统调用_C - Fatal编程技术网

在C中的参数中使用带shell元字符的execlp系统调用

在C中的参数中使用带shell元字符的execlp系统调用,c,C,程序:使用execlp()系统调用列出当前文件夹中的所有C文件: #include <stdio.h> #include <unistd.h> int main() { printf("Before Execl\n"); execlp("ls","ls","*.c",NULL); // this should print all c files in the current folder. return 0; } 每当我在搜索模式中使用“*”时

程序:使用
execlp()
系统调用列出当前文件夹中的所有C文件:

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

int main()
{
    printf("Before Execl\n");
    execlp("ls","ls","*.c",NULL); // this should print all c files in the current folder.
    return 0;
}
每当我在搜索模式中使用“
*
”时,我都会遇到类似的错误。请建议一些合适的解决方案。

应该是:

   execlp("ls", "*.c", NULL);
Exec不会像shell为您处理“
*
”操作符那样处理它。为此使用
popen()
glob\t
。你可以 我在2012-03-08问了一个类似的问题,想了解更多细节

execlp("ls", "*.c", NULL);

应该可以工作

如果希望扩展shell元字符,请调用shell来扩展它们,因此:

execlp("sh", "sh", "-c", "ls *.c", (char *)0);
fprintf(stderr, "Failed to exec /bin/sh (%d %s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
请注意,如果返回了
execl()
或任何
exec*
函数,则会失败。你不需要测试它的状态;它失败了。然后不应执行
退出(0)
(或
main()
函数中返回0;
),表示成功。有礼貌的做法是包含一条错误消息,概述出错原因,该消息应写入
stderr
,而不是
stdout
——如图所示

您可以自己进行元字符扩展;POSIX库中有一些函数可以提供帮助(例如)。但是让shell来做这件事要简单得多


(我已经修改了上面的代码,使用
execlp()
,以符合问题的要求。如果我不受限制地这样做,我可能会使用
execl()
,并指定
“/bin/sh”
作为第一个参数。);这没有帮助;shell进行元字符扩展,而不是执行系统调用。抱歉,这没有帮助。shell执行元字符扩展,而不是
exec*
系统调用。为什么
popen()
?您不准备写入
ls
命令,也不准备读取其输出,那么为什么您会从管道中受益呢?您提到的
glob\t
是一种与函数相关联的类型。请注意,如果您在调用
execlp
之前分叉,则在子级中使用
stdio
操作可能是错误的,除非您确定(1)程序是单线程的,(2)子级的
stderr
(或您正在使用的
文件中的任何一个)有资格成为“活动句柄”(参见POSIX XSH 2.5.1)。就我个人而言,我只想避免在
fork
之后使用非异步信号安全函数,其中还包括
退出
;改用
退出
。这是一种复杂的说法“如果你正常编程,你就没事了”。特别是,
stderr
通常是无缓冲的,并且得到“无需采取任何行动”“关于第三点,好的。正常无缓冲是一个实现细节。我记得,标准只是说默认情况下不应该完全缓冲,所以默认缓冲
stderr
行可能符合实现,可能会提供更好的性能。我会调用
fflush(stderr)
在分叉之前,如果您打算在分叉之后在父级和子级中使用它,为了安全起见。。。
execlp("sh", "sh", "-c", "ls *.c", (char *)0);
fprintf(stderr, "Failed to exec /bin/sh (%d %s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);