C: execvp() и аргументы командной строки

Итак, я пишу программу, в которой аргументы следующие:

program start emacs file.c

или даже

program wait

По сути, первый аргумент (argv[0]) — это имя программы, за которым следуют пользовательские данные.

Внутри моего кода я вызываю execvp. Дело в том, что я не совсем уверен, что привожу правильные аргументы.

if (pid == 0) { 
                    execvp(argv[1], argv); //Line of interest
                    exit(1);
                    }

являются ли argv[1] и argv правильными аргументами для описанной выше функциональности? Я просмотрел справочную страницу, и они имеют смысл, но могут быть неправильными для этого случая. Благодарю вас!


person user3295674    schedule 20.02.2014    source источник
comment
Из ответов вы заметите общую тему: execvp(cmds[n], &cmds[n]); или эквивалент. То есть вы передаете n-й элемент массива аргументов в качестве первого аргумента функции execvp() и передаете адрес n-го элемента массива аргументов в качестве второго аргумента — в вашем конкретном случае execvp(argv[1], &argv[1]);. Понятно, что технически вы не обязаны это делать (аргументы независимы), но вам нужна очень веская причина, чтобы поступить иначе.   -  person Jonathan Leffler    schedule 20.02.2014


Ответы (3)


В вашем основном argv будет таким в первом примере:

argv[0] = "program";
argv[1] = "start";
argv[2] = "emacs";
argv[3] = "file.c";
argv[4] = NULL;

В execv вы хотите запустить программу «start» с аргументами «emacs file.c», верно? Тогда первым параметром должен быть argv[1] - "start", а вторым - массив со следующими строками: {"start", "emacs", "file.c", NULL}. Если вы используете argv, вы включаете строку «программа» в argv[0].

Вы можете создать новый массив и скопировать эти параметры или использовать адрес argv[1] следующим образом:

execvp(argv[1], &argv[1]); //Line of interest
person Evans    schedule 20.02.2014

Единственное, что может быть проблемой, это то, что argv[0] в argv, переданном в execvp, не будет соответствовать argv[1] (первый аргумент). В остальном выглядит нормально.

Представьте, что вы звоните program cat file.txt. В вашей программе argv будет {"program", "cat", "file.txt", NULL}. Затем в cat, даже если вызываемый двоичный файл будет cat, argv все равно будет {"program", "cat", "file.txt", NULL}.

Поскольку cat пытается открыть и прочитать каждый аргумент как файл, первый файл, который он попытается открыть, будет cat (argv[1]), что не является желаемым поведением.

Простое решение — использовать execvp(argv[1], argv+1) — это существенно сдвигает массив аргументов влево на один элемент.

person millinon    schedule 20.02.2014

Насколько я понимаю, вы хотите выполнить определенное действие на основе второго аргумента командной строки (argv[1]). Если вторым аргументом является «start», ваша программа должна запустить исполняемый файл с именем argv[2] с аргументами, предоставленными после этого (правильно?). В этом случае вы должны предоставить execvp имя исполняемого файла (argv[2]) [1] и список аргументов, который по соглашению начинается с имени исполняемого файла (argv[2]).

execvp(argv[2], &argv[2]) реализует то, что мы описали в последнем абзаце (при условии, что это то, что вы намеревались сделать).

[1] execvp ожидает 2 аргумента, как вы знаете. Первый — это имя файла; если указанное имя файла не содержит символ косой черты (/), execvp выполнит поиск в переменной среды PATH (которая содержит список каталогов, в которых находятся исполняемые файлы), чтобы найти полное имя исполняемого файла. Второй аргумент — это список аргументов командной строки, которые будут доступны программе при ее запуске.

person Guilherme Salazar    schedule 20.02.2014
comment
Я почти уверен, согласно второму примеру, что argv[1] является предполагаемым целевым исполняемым файлом. - person millinon; 20.02.2014