execvp () возвращает значение, если путь указан неверно - PullRequest
0 голосов
/ 12 февраля 2019

В настоящее время я пишу собственный сценарий оболочки на C. Чтобы выполнить команду, я использую функцию execvp ().Например:

if((execvp(args[0], args)) == -1) //args is a char **array containing the commands arguments
{
    printf("ERROR: Wrong command\n");
    exit(EXIT_FAILURE);
}

Дело в том, что когда две команды разделены символом & &, если первая не выполнена (таким образом, execvp вернет -1), весь процесс должен прерваться, прежде чем мы пойдемк следующему.Это работает совершенно нормально, если, например, я напишу "<<strong> какая-то случайная неправильная команда > && ls".

Хотя, если я напишу что-то вроде "ls <<strong> какой-то случайный неверный путь > && ls ", execvp () будет выполнен нормально и напечатает сообщение:

ls: невозможно получить доступ к '...': Нет такого файла или каталога

Тогда он перейдет к следующей команде.По-видимому, в этом случае execvp () не возвращает -1.

Есть ли какое-либо другое значение, которое execvp () возвращает в этом случае?Если нет, как я могу проверить, существует ли путь перед выполнением команды?

РЕДАКТИРОВАТЬ Я просто проверяю значение статуса (генерируется ожиданием (и статусом), пока родитель ожидает ребенкапрекратить).Если он не равен нулю, это означает, что команда не была выполнена.

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Хотя, если я напишу что-то вроде "ls&& ls ", execvp () будет выполнен нормально и напечатает сообщение:

ls: невозможно получить доступ к '...': нет такого файла или каталога

Затем он перейдет к следующей команде. Очевидно, что в этом случае execvp () не возвращает -1.

Возвращаемое значение execvp() сообщает о том, был ли успешно выполнен образ процесса замены"d. Он не имеет никакого отношения к состоянию выхода любой замены. И, конечно, он вообще возвращается только при невозможности замены текущего образа процесса новым. Это единственный способ может работать, поскольку замещающее изображение должно быть успешно загружено и запущено до того, как будет определено его состояние выхода, и в этот момент предыдущее изображение больше не доступно для возврата в .

Есть ли какое-либо другое значение, которое execvp () возвращает в этом случае?

No.

Если нет, как я могу проверить, еслипуть существует до выполнения команды?

Thэто неправильная стратегия.Ваша оболочка должна знать, как проверять все операнды для каждой команды, которую она когда-либо могла выполнить, чтобы это работало в общем случае.Это просто невозможно для оболочки, которая позволяет выполнять произвольные программы.

Вам нужно получить статус выхода первого процесса через wait или waitpid.Если вы делаете это даже удаленно правильно, то вы уже используете один из них, чтобы дождаться завершения первого процесса перед запуском второго, и, естественно, вы не можете определить состояние выхода, пока процесс фактически не завершится.Каждая из функций wait() и waitpid() может предоставить int код «статуса», из которого вы можете извлечь различную информацию о процессе, который завершился, включая, в случае нормального завершения, его состояние выхода.

0 голосов
/ 12 февраля 2019

Есть ли какое-либо другое значение, которое execvp () возвращает в этом случае?

execvp не возвращает любое значение в этом случае, потому что ему удалось выполнить команду, которую вы попросили.Вы не можете получить ошибку от ls, если ls не был успешно выполнен.Вы, вероятно, хотели, чтобы ваш && замкнул накоротко не только при сбое exec, но и при успешном exec, когда exec'd-процесс возвращает ненулевой код состояния (как указано wait / waitpid).

Если нет, как я могу проверить, существует ли путь перед выполнением команды?

Вообще говоря, это не имеет никакого смысла.Для оболочки не принято делать предположения о том, как команды, которые она выполняет, будут интерпретировать свои аргументы, например, что одна из них должна быть именем существующего файла.Даже если у вас действительно был такой особый случай, он будет зависеть от состояния гонки (файл существует при проверке оболочки, но не при запуске ls, или наоборот).

...