Как заставить chdir() оставаться в указанном каталоге после завершения программы?

У меня есть программа, которая вызывает chdir() для изменения cwd. Однако после завершения программы cwd переходит обратно в каталог, который вызвал программу, вместо того, чтобы оставаться в каталоге, указанном вызовом chdir(). Я создал программу для проверки, действительно ли chdir() действительно переходит в указанный каталог, и обнаружил, что chdir() выполняет то, что я предполагал: переход в указанный каталог на время выполнения программы, а затем возврат в каталог, в котором выполнялась программа.

Вот код для теста:

#include <stdio.h>
#include <unistd.h>

#define NAME_MAX 100

int main(int argc, char **argv)
{
    char buf[NAME_MAX];
    char *path = argv[1];

    if (chdir(path) == -1) { /* change cwd to path */   
        fprintf(stderr, "error: could not change to dir %s\n", path);
        return 1;
    }
    getcwd(buf, NAME_MAX);
    printf("CWD is: %s\n", buf); /* print cwd as obtained from getcwd() */

    return 0;
}

и вот вывод из моего терминала:

john@ubuntu:~/C/cli$ pwd
/home/john/C/cli
john@ubuntu:~/C/cli$ mkdir foobar
john@ubuntu:~/C/cli$ ./test.c foobar
CWD is: /home/john/C/cli/foobar
john@ubuntu:~/C/cli$ pwd
/home/john/C/cli

Итак, мой вопрос, как я могу остаться в каталоге, который я указываю при вызове chdir() после завершения программы? Кроме того, я нахожусь на Ubuntu 12.04 и компилирую с помощью gcc.

2 ответа

Решение

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

Вот почему chdir является встроенной командой в оболочке; это не может быть реализовано как отдельная программа.

Если вы хотите, чтобы программа изменила текущий каталог вашей оболочки, вам нужно будет сделать это косвенно. Например, ваша программа может распечатать cd команда, и вы можете eval этот вывод в вашей оболочке. (Вы можете обернуть это в функцию.)

Например, если вы измените:

chdir(path);

в

printf("cd %s\n", path);

у вас может быть функция оболочки:

my_func() {
    eval `your_program`
}

а также my_func изменит текущий каталог вашей оболочки.

Или вы можете положить cd Команда непосредственно в функции или в сценарии, который вы выполняете через . script-name или же source script-name вместо того, чтобы выполнять это.

Все эти решения требуют вашей текущей оболочки для выполнения cd сама команда (которая внутренне вызывает chdir системный вызов).

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

Другие вопросы по тегам