[英]execvp command not running ls -l *.c
我的execvp
没有运行ls -l *.c
命令。 我尝试使用两种方法:
\bin\ls
中。#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
char *cmdargs[] = { "ls", "-l", "*.c", NULL };
pid_t pid;
pid = fork();
if (pid == 0)
execvp("\bin\ls", cmdargs);
else
{
wait(NULL);
printf("Child terminates\n");
}
return 0;
}
Output:
ls: *.c: No such file or directory
Child terminates
cmdargs[0]
而不是文件路径。#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
char *cmdargs[] = { "ls", "-l", "*.c", NULL };
pid_t pid;
pid = fork();
if (pid == 0)
execvp(cmdargs[0], cmdargs);
else
{
wait(NULL);
printf("Child terminates\n");
}
return 0;
}
Output:
ls: *.c: No such file or directory
Child terminates
当我只运行命令ls -l *.c
时,它会显示所有以.c
结尾的文件。 Execvp 没有向我显示文件。 有一个与此相关的问题,但这对我没有帮助。
GLOB 模式由 shell 扩展,而不是ls
本身。 您可以通过 exec 创建一个子 shell 来实现您想要的。 这是一个例子:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
char *cmdargs[] = { "sh", "-c", "ls -l *.c", NULL };
pid_t pid;
pid = fork();
if (pid == 0) {
execvp(cmdargs[0], cmdargs);
} else {
wait(NULL);
printf("Child terminates\n");
}
return 0;
}
如果需要,您也可以为此使用system(3)
。
星号模式*
由 shell 进行,但由ls
进行。
例如,您可以将exec
与sh
一起使用。
编辑 OP 的响应,获取所有文件而不使用字符串数组中的*.c
并根据需要过滤字符串。
当您输入ls -l *.c
时,shell 将解析该命令,找到 glob 模式并将其展开。 然后它将使用扩展的参数列表调用ls
,使用像{"ls", "-l", "ac", "bc", "cc", NULL}
这样的数组调用execvp
。 ls
和execvp
都不会自行扩展 glob,它是 shell 做到的。
因此,如果您想使用 glob,您的选择是自己扩展它们(通过手动浏览当前目录并将所有以.c
结尾的文件添加到您的数组或使用 POSIX glob 函数),或者通过 go shell。 您可以通过使用{"sh", "-c", "ls -l *.c", NULL}
作为传递给execvp
的数组来显式调用来执行后者(或者类似地,但没有数组,使用execl
等)或者您可以使用system("ls -l *.c")
,它总是通过 shell。
Note that you definitely don't want to go through the shell if the arguments contain untrusted user input, so in that case expanding the glob(s) yourself / using glob
would be the way to go.
Alternatively to invoking the shell to expand the *.c
glob pattern to files, you can use glob to expand *.c
to list of files yourself and then construct a dynamically allocated array of arguments.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <glob.h>
#include <stdlib.h>
int main() {
glob_t result = {0};
int err = glob("*.c", GLOB_ERR, NULL, &result);
if (err) return err;
char **cmdargs = malloc((2 + result.gl_pathc + 1) * sizeof(cmdargs));
if (cmdargs == NULL) return EXIT_FAILURE;
cmdargs[0] = "ls";
cmdargs[1] = "-l";
for (size_t i = 0; i < result.gl_pathc; ++i) {
cmdargs[i + 2] = result.gl_pathv[i];
}
cmdargs[2 + result.gl_pathc] = NULL;
pid_t pid = fork();
if (pid == 0) {
execvp(cmdargs[0], cmdargs);
} else {
wait(NULL);
printf("Child terminates\n");
}
globfree(&result);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.