Как передать аргумент (который является командой вместо имени файла) в новую оболочку с помощью execve?

Я пытаюсь отправить аргументы (например: ls, date, cal) в новую оболочку, выполнить эти аргументы и завершить работу.

  #include"header.h"  //includes all the header files

 int main(int argc,char * argv[],char *envp[]) {
     char *ap[]={"sh","ls",NULL};
     int p=execve("/bin/sh",ap,envp);
     printf("error:%d",p);

     perror("execve");

 }

выход:

sh:0:can't open ls

person Totla Sathish    schedule 22.09.2017    source источник
comment
Header.c определяется пользователем и включает все необходимые библиотечные файлы.   -  person Totla Sathish    schedule 22.09.2017
comment
как насчет char *ap[]={"ls",NULL};   -  person Jean-François Fabre    schedule 22.09.2017
comment
Я не уверен на 100%, что понимаю, что вы пытаетесь сделать, но я думаю, что это должно быть {"sh", "-c", "ls", 0}. -c означает, что следующим аргументом является команда; без него первый аргумент, не являющийся опцией, для sh интерпретируется как имя вызываемого сценария оболочки.   -  person zwol    schedule 22.09.2017


Ответы (1)


Это не имеет ничего общего с execve. Ваша программа правильно вызывает sh ls.

Просто sh интерпретирует свой первый аргумент как имя запускаемого сценария оболочки, но в текущем каталоге нет файла с именем ls, отсюда и ошибка. Вы получите те же результаты, запустив sh ls вручную.

Если все, что вы хотите сделать, это запустить ls, зачем вообще проходить через оболочку? Просто сделать:

char *ap[]={"ls",NULL};
int p=execve("/usr/bin/ls",ap,envp);

С другой стороны, если вы хотите использовать оболочку, вам нужно сообщить ей, что ее аргументом должна быть команда, а не имя файла. Вы делаете это с sh -c ls:

char *ap[]={"sh","-c","ls",NULL};
person melpomene    schedule 22.09.2017
comment
Или execlp("ls", "ls", (char *)0) для поиска пути. (Примечание: приведение char * необходимо, даже если вы предпочитаете записывать нулевые указатели как NULL.) - person zwol; 22.09.2017
comment
Спасибо за вашу помощь - person Totla Sathish; 22.09.2017
comment
@zwol Ах да, актерский состав необходим из-за ... из int execlp(const char *file, const char *arg, ...); - person chux - Reinstate Monica; 22.09.2017
comment
@zwol Я всегда делаю (char *)NULL, но я думаю, что приведение технически не требуется на платформах, которые определяют NULL как ((void *)0). - person melpomene; 22.09.2017
comment
@melpomene Нет, это необходимо, даже если это определение NULL, потому что void * и char * не требуется передавать одинаково через список переменных аргументов. (У меня есть смутное воспоминание о том, что C11 изменил это, но я не помню точно, и в любом случае это около 15 лет слишком рано, чтобы предполагать C11.) - person zwol; 22.09.2017
comment
@zwol Ах, очень весело. - person melpomene; 22.09.2017