2012-03-25 3 views
4

Я знаю, что cd - это встроенная оболочка, и я могу запустить ее с помощью system().Использование семейства exec() для запуска команды «cd»

Но возможно ли выполнить команду cd от семьи exec(), например execvp()?

Редактировать: И я просто заметил, что system("cd") также бессмысленны. Спасибо за помощь.

ответ

10

exec загружает исполняемого файл и заменяет текущую программу изображения вместе с ним. Как вы правильно отметили, cd is не исполняемый файл, а скорее встроенная оболочка. Таким образом, исполняемый файл, который вы хотите запустить, является самой оболочкой. Это, конечно, что system() делает для вас, но если вы хотите быть явно об этом, вы можете использовать exec:

execl("/bin/sh", "-c", "cd", (const char *)0); 

С этого заменяет текущим образ процесса, вы должны сделать это после того, как fork() ИНГА от новый процесс.

Однако вся эта процедура абсолютно не влияет. Если вы хотите изменить каталог в текущем процессе, используйте chdir().

+0

Можете ли вы пройти через то, что представляет собой аргумент? – User

+0

@User: Аргументы составляют исполняемую команду, и поскольку это функция с переменными аргументами, мы должны каким-то образом сигнализировать о конце аргументов, которые в этом случае выполняются пустым указателем типа 'const char * '. Таким образом, выполняемая команда: '/ bin/sh -c cd' –

10

Вам лучше использовать int chdir(const char *path); найдено в unistd.h.

+0

+1 для упоминания необходимую функцию. – glglgl

2

Нет, это не так, и это бесполезно. chdir (функция, которая изменяет текущий каталог процесса) влияет только на процесс, который вызывает его (и его дочерние элементы). В частности, это не влияет на его родителя.

Таким образом, exec ing не имеет смысла, так как процесс будет немедленно сходить после изменения каталогов.

(Вы могли бы что-то вроде EXEC bash -c cd /tmp, если вы действительно хотите, но, как я уже сказал, это бесплодное.)

3

Хотя, как уже указывалось, system("cd xxx") не изменит вашу текущую директорию приложения, это не совсем бесполезно.

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

Точно так же, если вы, как комплексные решения, вы также можете сделать то же самое с вилкой/Exec, либо с exec'ing /bin/sh -c cd xxx или просто /bin/cd xxx с операционкой, которые обеспечивают независимую cd исполняемый файл.

Я бы, однако рекомендовать эту неоднозначность излишним быстрее эквивалентной access("xxx", X_OK|R_OK)

Примечание: Все POSIX совместимые операционные системы must обеспечить независимый кд исполняемый файл. Это по крайней мере в случае с Solaris, AIX, HP-UX и Mac OS/X.

+1

Независимый исполняемый файл' cd' просто и просто невозможно. – glglgl

+0

В ОС, которые я использую, определенно один. – jlliagre

+0

@jliagre: резервное копирование последнего абзаца указателями. Например. ссылку на конец http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap01.html, где говорится, что * все стандартные утилиты, включая обычные встроенные модули [...], должны быть реализованы таким образом, чтобы к ним можно было получить через семейство функций exec *. И для cd-пользователя Solaris http://docs.oracle.com/cd/E19253-01/816-5165/6mbb0m9bl/index.html, который указывает, что */usr/bin/cd не влияет на процесс вызова, но может быть использован чтобы определить, может ли данный каталог быть установлен в качестве текущего каталога * – adl

0

Когда вилка выполнена, переменная среды CWD (текущая рабочая директория) наследуется дочерним элементом из родителя.Если fork и exec выполняются так, как обычно, дочерний вызов вызывает chdir(), который просто меняет каталог на новый каталог и выходит, но это не влияет на родителя. Причина: новая среда потеряна.

Смежные вопросы