Разница между exec, execvp, execl, execv? - PullRequest
0 голосов
/ 18 апреля 2019

Я пишу код, который представляет новую оболочку для Linux.Одной из команд, которые я хочу поддержать, является запуск процесса, например, если я получаю следующую строку

command [arguments]

Затем я хочу запустить command какпроцесс до его завершения.

Для этого я знаю, что мне нужно использовать fork(), чтобы получить дочерний процесс и получить его PID, моя проблема в том, что я не знаю, чторазница между:

exec, execvp, execl, execv ... и я не знаю, какой использовать и почему.

Мой текущий код:

void External_Process(char *arguments[MAX_ARG], char* command)
{
    int pID;
    switch(pID = fork())
    {
    case -1:
        perror("fork failed");
        break;
    case 0 :
        setpgrp();

        //execv(command, arguments);
        //execvp(command, arguments);
        //execl("/bin/bash", "/bin/bash","-c",command,NULL);

        printf("smash error: > bad command %s\n" , command);
        exit(-1) ;

        break;

    default:
        return ;
    }
}

Спасибо!

Ответы [ 3 ]

0 голосов
/ 18 апреля 2019

В C вы можете использовать команду 'system'.Это выполнит то, что вы вводите в качестве аргумента функции.

Вот пример:

system("ls -l");

Если вы хотите получить выходные данные, вы можете перенаправить их на другой источник.

0 голосов
/ 18 апреля 2019

Резюме: В вашем случае я бы порекомендовал использовать execvp.

Чтобы выяснить различия между функциями exec*, вам следует прочитать документацию:
https://linux.die.net/man/3/exec
https://linux.die.net/man/2/execve

Разница между execl* и execv* заключается в передаче аргумента.execl* требует список аргументов, в то время как execv* требует вектор аргументов.
Список аргументов полезен, если вы знаете все аргументы во время компиляции.В вашем случае аргументы будут введены пользователем, и вы должны создать вектор аргументов во время выполнения, поэтому вы должны использовать одну из execv* функций.

Функции с суффиксом p используютпеременная окружения PATH для поиска программы (например, "ls"), без этого вам нужно указать полный путь (либо абсолютный, либо относительно текущего каталога, например, "/bin/ls").Использование PATH - это то, что обычно делают оболочки, так что это, кажется, правильный выбор для вас.

Функции с суффиксом e позволяют указать среду для процесса.Для простоты я бы не использовал это в вашем случае.

Это приводит к выводу: execvp

Конечно, вы также можете использовать system (вместо fork / * 1036).* / wait*), как упомянуто в ответе vladxjohn, но в этом случае вы бы просто использовали оболочку для интерпретации вашей команды вместо реализации базовой оболочки.

0 голосов
/ 18 апреля 2019

Попробуйте прочитать руководство: https://linux.die.net/man/3/execv

Выдержка:

Описание Семейство функций exec () заменяет текущий образ процесса новым образом процесса.Функции, описанные на этой странице руководства, являются внешними для execve (2).(См. Страницу руководства для execve (2) для получения дополнительной информации о замене текущего образа процесса.)

Начальным аргументом для этих функций является имя файла, который должен быть выполнен.

const char * arg и последующие эллипсы в функциях execl (), execlp () и execle () можно рассматривать как arg0, arg1, ..., argn.Вместе они описывают список из одного или нескольких указателей на строки с нулевым символом в конце, которые представляют список аргументов, доступных для исполняемой программы.Первый аргумент, по соглашению, должен указывать на имя файла, связанное с исполняемым файлом.Список аргументов должен заканчиваться указателем NULL, и, поскольку они являются переменными функциями, этот указатель должен быть приведен (char *) NULL.

execv (), execvp () и execvpe ()функции предоставляют массив указателей на строки с нулевым символом в конце, которые представляют список аргументов, доступный для новой программы.Первый аргумент, по соглашению, должен указывать на имя файла, связанное с исполняемым файлом.Массив указателей должен заканчиваться указателем NULL.

Функции execle () и execvpe () позволяют вызывающей стороне указывать среду исполняемой программы через аргумент envp.Аргумент envp представляет собой массив указателей на строки с нулевым символом в конце и должен заканчиваться указателем NULL.Другие функции получают среду для нового образа процесса из внешней переменной среды в вызывающем процессе.

Специальная семантика для execlp () и execvp ()

execlp (), execvp () и функции execvpe () дублируют действия оболочки при поиске исполняемого файла, если указанное имя файла не содержит символ косой черты (/).Файл ищется в списке разделенных двоеточиями каталогов, указанных в переменной среды PATH.Если эта переменная не определена, по умолчанию в списке путей указан текущий каталог, за которым следует список каталогов, возвращаемый confstr (_CS_PATH).(Этот вызов confstr (3) обычно возвращает значение "/bin:/usr/bin".)

...