Подтвердить что ты не робот

Я не понимаю, как execlp() работает в Linux

Я провел последние 2 дня, пытаясь понять системный вызов execlp(), но все же я здесь. Позвольте мне прямо ответить на этот вопрос.

man page execlp объявляет системный вызов как int execlp(const char *file, const char *arg, ...); с описанием: аргумент const char и последующие эллипсы в функциях execl(), execlp() и execle() можно рассматривать как arg0, arg1,..., argn.

Тем не менее, я вижу, что системный вызов называется так в нашем учебнике: execlp("/bin/sh", ..., "ls -l /bin/??", ...); ( "..." для нас нужно найти в качестве студентов). Однако этот системный вызов даже не похож на объявление в man page системного вызова.

Я смущен. Любая помощь приветствуется.

4b9b3361

Ответ 1

этот прототип:

  int execlp(const char *file, const char *arg, ...);

Говорит, что execlp - функция переменных аргументов. Требуется 2 const char *. Остальные аргументы, если таковые имеются, являются дополнительными аргументами для передачи в программу, которую мы хотим запустить, а также char * - все это C строк (и последний аргумент должен быть NULL-указателем)

Итак, аргумент file - это путь к исполняемому исполняемому файлу. arg - это строка, которую мы хотим отобразить как argv[0] в исполняемом файле. По соглашению, argv[0] - это просто имя файла исполняемого файла, обычно оно устанавливается так же, как file.

... теперь являются дополнительными аргументами для выполнения исполняемого файла.

Предположим, вы запустили это из командной строки/оболочки:

$ ls

Это будет execlp("ls", "ls", (char *)NULL); Или если вы запустите

$ ls -l /

Это будет execlp("ls", "ls", "-l", "/", (char *)NULL);

Итак, на execlp("/bin/sh", ..., "ls -l /bin/??", ...);

Здесь вы перейдете в оболочку /bin/sh, и вы даете оболочке команду для выполнения. Эта команда - "ls -l/bin/??". Вы можете запустить это вручную из командной строки/оболочки:

 $ ls -l /bin/??

Теперь, как вы запускаете оболочку и говорите ей, чтобы выполнить команду? Вы открываете документацию/страницу для своей оболочки и читаете ее.

Что вы хотите запустить:

$ /bin/sh -c "ls -l /bin/??"

Это становится

  execlp("/bin/sh","/bin/sh", "-c", "ls -l /bin/??", (char *)NULL);

Боковое примечание: /bin/?? выполняет сопоставление с образцом, это сопоставление шаблонов выполняется оболочкой, и оно распространяется на все файлы в/bin/с двумя символами. Если вы просто сделали

  execlp("ls","ls", "-l", "/bin/??", (char *)NULL);

Вероятно, ничего не получится (если нет файла с именем /bin/??), поскольку нет оболочки, которая интерпретирует и расширяет/bin/??

Ответ 2

Ограничение execl заключается в том, что при выполнении команды оболочки или любого другого script, который не находится в текущем рабочем каталоге, мы должны передать полный путь к команде или script. Пример:

execl("/bin/ls", "ls", "-la", NULL);

Обходным путем для передачи полного пути исполняемого файла является использование функции execlp, которая ищет файл (1-й аргумент execlp) в тех каталогах, на которые указывает PATH:

execlp("ls", "ls", "-la", NULL);