Ответ 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/??