在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);