Написание оболочки - как определить путь к исполняемому файлу и имя файла для различных вызовов exec

0

У меня есть проект для написания оболочки в C++ в операционной системе Linux, которая может запускать подмножество команд, которые терминал может запускать как cd, ls и т.д.

Мой вопрос: если я использую что-то вроде execl("bin/ls","ls") как он знает, где выполнить ls. Будет ли он по умолчанию просто запускать ls из каталога, из которого запускается программа. И если да, то как мне изменить, где он работает от, если я запустил cd foo а затем снова запустил ls. Да, я делаю довольно ограниченную версию bash.

Вот что я до сих пор запустил ls.

int quash :: ls (строка)

{
        pid_t child = 0;
        child = fork();

        if (child < 0)
        {
            fprintf( stderr, "process failed to fork\n" );
            return 1;
        }
        if (child == 0)
        {
            wait(NULL);
        }
        else
        {
            execlp("/bin/ls", "ls");
        }
        return 0;
    }

Будет ли execlp() "/bin/ls", "ls"); распечатать что-нибудь или мне нужно добавить что-то еще?

  • 0
    Это больше похоже на «оболочку», чем «эмулятор терминала». Предположительно, вы должны либо использовать chdir (2) перед вызовом функции exec () - family, либо передать желаемый каталог в качестве аргумента в зависимости от желаемого поведения.
  • 1
    Переменная окружения PATH может сыграть свою роль ...
Показать ещё 2 комментария
Теги:
posix

1 ответ

3

Резюме

Если вы вызываете execl("bin/ls", "ls") система попытается найти файл с именем ls в каталоге с именем bin внутри текущего рабочего каталога. Это почти наверняка не то, что вы хотите сделать. Вы, вероятно, хотите:

execlp("ls", "ls);

или

execl("/bin/ls", "ls");

Хотя также возможно, что ни то, ни другое не требуется.

Подробнее

Существует множество различных функций, которые могут быть использованы для замены текущего процесса новым изображением процесса; они включают, по меньшей мере, следующее:

execl,  execv
execle, execve
execlp, execvp

Варианты, которые включают l, являются вариабельными; они берут NULL-конец списка аргументов const char* которые определяют вектор argv который должен быть передан новому исполняемому файлу. Версии, которые включают в себя v вместо этого, принимают один аргумент char*const[], который представляет собой массив строк с нулевым завершением, которые используются для построения вектора argv.

Версии, которые заканчиваются на e принимают один дополнительный аргумент, который является char *const[] используемым для создания новых переменных исполняемой среды. В других версиях используется существующая коллекция переменных среды.

Версии, которые заканчиваются на p обрабатывают первый аргумент по-разному двумя способами:

  1. Если первый аргумент не содержит /, тогда (текущая) PATH среды PATH используется для поиска правильной директории. Ожидается, что PATH будет списком путей к каталогам, разделенных :, и имя файла (то есть первый аргумент execlp или execvp) будет искать в каждом каталоге по очереди. Если первый аргумент содержит /, то он обрабатывается так же, как и другие варианты exec: первый аргумент должен быть фактическим путем к исполняемому файлу, который обычно является абсолютным путем (то есть, который начинается с /), хотя допускается относительный путь, и в этом случае он будет относиться к текущему рабочему каталогу.

  2. Кроме того, если файл найден, но он не распознается как исполняемый двоичный файл, он будет рассматриваться как сценарий оболочки, будучи переданным оболочке по умолчанию (обычно /bin/sh). Версия non- p exec возвращает ошибку в этом случае. (Это не то же самое, что исполнение "shebang", которое не указано Posix, но которое обычно будет выполняться загрузчиком системного образа, чтобы оно работало с любым вариантом exec.)

Для интерпретаторов оболочки версии v намного удобнее. Это прискорбно, что нет версии, которая предлагает как e и p опции (хотя библиотека GNU C glibc действительно обеспечивает один, execvpe), потому что без этой возможности, нет никакого способа, чтобы получить автоматический поиск пути с текущей PATH переменной; только с новой PATH.

Рекомендации:

  1. Определение Posix: http://pubs.opengroup.org/onlinepubs/9699919799/functions/execl.html

  2. Linux manpage для execveglibc, все остальные варианты exec конечном итоге вызывают execve): http://linux.die.net/man/2/execve

  3. Linux manpage для остальных вариантов exec: http://linux.die.net/man/3/exec

Ещё вопросы

Сообщество Overcoder
Наверх
Меню