Как передать дополнительную опцию в ls, используя execv ()? - PullRequest
0 голосов
/ 09 декабря 2018

Я пытаюсь выполнить эту простую команду ls -1 *.c с помощью функции execv ().

#include<stdio.h>
#include<fcntl.h>
int main(int argc,char* argv[]){
char *arr[3]={"ls","-1","*.c"};
execv("/bin/ls",arr);
}

Вывод, который я получаю,

ls: cannot access *.c: No such file or directory

1 Ответ

0 голосов
/ 09 декабря 2018

В вашем коде есть большая проблема: execv не может определить, насколько велик массив, который вы передаете.Вам абсолютно необходим завершающий элемент NULL, чтобы отметить конец:

char *arr[] = { "ls", "-1", "*.c", NULL };

ОК, теперь, когда у нас есть действительный вызов execv, мы можем справиться с ошибкой ls.

Вызов execv, подобный этому, эквивалентен запуску

'ls' '-1' '*.c'

в командной строке (что приведет к такой же ошибке).

Когда вы делаете

ls -1 *.c

в командной строке ls никогда не видит *.c, поскольку оболочка расширяет символы подстановки и передает список совпадающих имен файлов в ls.

Если вы хотите повторить это в своем коде C, выдолжны сделать то же самое вручную.Смотрите, например, man glob для функции, которая выполняет большую часть работы.Вот адаптированный пример со страницы руководства, где показан общий принцип:

glob_t globbuf;

globbuf.gl_offs = 2;
glob("*.c", GLOB_DOOFFS, NULL, &globbuf);
globbuf.gl_pathv[0] = "ls";
globbuf.gl_pathv[1] = "-1";
execv("/bin/ls", globbuf.gl_pathv);
...