C ++ - Linux / shell скрипт запускает дочерние процессы и получает их статусы возврата - PullRequest
2 голосов
/ 31 июля 2011

Я ищу решение для написания части программы на C ++ для Linux, которая анализирует файл, содержащий программы с заданными аргументами, а затем запускает эти программы с аргументами аргументов.

Каждая программа (строка) выполняется по одной за раз, а затем родительский процесс ожидает выхода каждого дочернего элемента и проверяет его состояние выхода (меня интересует только 0).

Пример текста для разбора:

prog1 -a arg1 -m arg2 -c arg3 prog2 arg1 arg2 arg3 arg4 ....

Я считаю, что лучше хранить все в векторестрок, например:

vector <std::string> p_vector;
while (getline(file, line))
    p_vector.push_back(line);

затем для каждого элемента i от 0 до p_vector.size () мне нужно сделать что-то похожее на пример, который я нашел в сети:

if(fork() = 0) //? shouldn't here be == ?
{
    execv(fullpath,argv);//does full path mean my p_vector[i]? or the child process and then argv is a list of space delimited arguments?
    exit(1);
}
else
{
    int *status;
    wait(status);
    if(*status == 0)
    printf("%s exited correctly", fullpath);//fullpath, right?
    else
    //other printf error
}

или мне лучше использовать для этого

string command = p_vector[i]; // eg: ls -l -a -l folder_one , put more arguments because I do not know the exact number of them for each parsed line

int exitCode = system(command.c_str());

Если у кого-то есть идея, как сделать это с помощью скрипта, это тоже будет приветствоваться, хотя сфера моего вопроса - C ++!

Я мог бы использовать QProcess Qt, так как знаю, как его использовать, но это может вызвать некоторые юридические проблемы, о которых я сейчас знаю (однако проблем с совместным использованием кода нет, компания, в которой я работаю, можетне позволю это)

Спасибо и с нетерпением жду получения такмне ответы от тебя!

Ответы [ 3 ]

0 голосов
/ 31 июля 2011

Я согласен с Игнасио.Но если вам нужно это сделать, то я бы предпочел, чтобы вы использовали команду System / popen.

НО УБЕДИТЕСЬ, ЧТО ВЫ НЕ ВЫПОЛНЯЕТЕ ЛЮБУЮ КОМАНДУ, КОТОРУЮ ВЫ ПОЗВОЛЯЕТЕ УЖАСИТЬ ... как "rm -rf *".

Это очень вероятно произойдет, если вы собираетесь читать из файла, которому нельзя доверять.

И нет необходимости копировать его в новую строку, которую вы можете сделать "system (p_vector [я] .c_str ());»

0 голосов
/ 31 июля 2011

Чтобы использовать семью exec, вам нужно разобрать ваши p_vector[i] в токены. Нулевой токен определяет программу, которая будет выполнена; остальные указывают аргументы программы. execvp эмулирует то, что делает ваша оболочка: она ищет программу в пути поиска. execv ожидает, что вы пойдете еще дальше. Вам необходимо указать путь к программе, но не обязательно полный путь; Относительные пути работают просто отлично. Еще одна небольшая ошибка в отношении exec: нулевой аргумент должен быть точной копией имени программы. Это большая работа в этом случае.

По существу, system делает следующее:

int pid, status, wait_pid;
char * shell;

shell = getenv ("SHELL");
if (shell == 0) {
   // Deal with missing SHELL environment variable problem
   return -1;
}

pid = fork();
if (pid < 0) {
    return -1;
}

else if (pid == 0) {
   execl (shell, shell, string_to_execute);
   return -1;
}

waited_pid = waitpid (pid, &status, wait_options);
if (waited_pid != pid) {
   return -1;
}

return status;

Другими словами, в значительной степени то, что вы хотите.

Редактировать 1
Один попался с system: небезопасно, как все выходят. АрунМу уже упоминал rm -rf /. Что делать, если какая-то строка содержит do_something_benign; rm -rf / Если вы можете доверять содержимому файла, использовать system хорошо. Если нет, то гораздо лучше использовать что-то вроде perl или другого языка сценариев, который можно настроить для работы в безопасном режиме.

Редактировать 2
Учитывая комментарии, что является движущим фактором, который заставил вас захотеть написать это на C или C ++? Язык сценариев или, что еще лучше, цель test в вашем make-файле лучше подходит для этой проблемы.

0 голосов
/ 31 июля 2011

в Баш:

echo file | while read command
do
   eval $command
done

где file - файл, содержащий для каждой строки программу с его аргументами

...