[英]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.