Execve: как я могу инициализировать char *argv[ ] несколькими командами вместо одной?
Если я хочу выполнить 4 команды, могу ли я использовать следующий оператор?

char *argv[4][ ] = { {...}, {...}, {...} };

И чтобы выполнить их с помощью execve, могу ли я использовать цикл с переменной от 1 до 4?

5
Linuxknowledgeseeker 26 Июл 2017 в 09:12
Семейство функций exec предназначено для выполнения только одной программы. Вы не можете использовать их для выполнения нескольких программ. Особенно через массив argv, который exec не использует для поиска программы для выполнения.
 – 
Some programmer dude
26 Июл 2017 в 09:15
Вам придется использовать петлю. execve будет выполнять только первую программу, а остальные команды рассматривать как аргументы первой. Вы правы, вам придется использовать цикл.
 – 
Ajay Brahmakshatriya
26 Июл 2017 в 09:17
Да, и не забудьте fork новый процесс в цикле, так как успешный вызов execve не вернется.
 – 
Some programmer dude
26 Июл 2017 в 09:25
Инструмент для выполнения пакета команд - это оболочка, поэтому вы можете execve() /bin/sh с правильным списком аргументов --- или, как уже говорилось, делать сами то, что делает оболочка (fork() , execve() и wait() ... или posix_spawn() и wait())
 – 
user2371524
26 Июл 2017 в 09:40
@Someprogrammerdude, точнее сказать, - это системный вызов, предназначенный только для загрузки образа программы в память и начала его выполнения . ИМХО.
 – 
Luis Colorado
27 Июл 2017 в 11:50

1 ответ

Вы не можете выполнять несколько команд с помощью одного вызова execve. В цикле вам потребуется fork ваша программа для выполнения нескольких вызовов execve. На странице руководства execve написано:

execve () не возвращает результат в случае успеха, а текст, данные, bss и стек вызывающего процесса перезаписываются текстом загруженной программы. [...]

Возвращаемое значение
В случае успеха execve () не возвращает, в случае ошибки возвращается -1 и errno установлен соответствующим образом.

Метод с использованием fork:

Выход:

Hello 1
Hello 2
Hello 3

Код:

#include <unistd.h>
#include <stdio.h>

int main(void)
{
   int idx;
   char *argv[][4] = { {"/bin/sh", "-c", "echo Hello 1", 0},
                       {"/bin/sh", "-c", "echo Hello 2", 0},
                       {"/bin/sh", "-c", "echo Hello 3", 0} };
   for (idx = 0; idx < 3; idx++)
   {
      if (0 == fork()) continue;
      execve(argv[idx][0], &argv[idx][0], NULL);
      fprintf(stderr, "Oops!\n");
   }

   return 0;
}

Метод с использованием конкатенации команд:
Обходной путь - объединить команды с помощью оболочки:

Выход:

Hello 1
Hello 2

Код:

#include <unistd.h>
#include <stdio.h>

int main(void)
{
   char *argv[] = {"/bin/sh", "-c", "echo Hello 1 && echo Hello 2", 0};
   execve(argv[0], &argv[0], NULL);
   fprintf(stderr, "Oops!\n");

   return 0;
}
4
Andre Kampling 26 Июл 2017 в 10:06
Привет, @Linuxknowledgeseeker, если этот или любой ответ помог решить ваш вопрос, пожалуйста, примите его, нажав галочку. Это показывает широкому сообществу, что вы нашли решение, и дает некоторую репутацию как автору, так и вам. Это не обязательно.
 – 
Andre Kampling
16 Авг 2017 в 09:41