POSIX/C: chdir() не меняет каталог с пробелами?

Я пытаюсь разработать оболочку в C/POSIX в своей Mac OS X. Для команды cd я могу успешно изменить каталог оболочки с помощью метода chdir в большинстве случаев, за исключением случаев, когда в пути есть пробелы. Например, такой путь, как

/users/bayesianStudent/desktop

правильно меняет каталог, но следующее,

/users/bayesianStudent/desktop/Spring\ 2016

вернуть сообщение об ошибке:

No such file or directory

Однако, если я выберу тот же путь и использую обычный терминал, он работает нормально (так что с путем все в порядке). Ниже приведена фиктивная программа, которая воспроизводит проблему:

#include    <stdio.h>
#include    <stdlib.h>

int main()
{
    char path[1024];
    char cwd[1024];

    printf("Please enter path:\n");
    gets(path);
    printf("Trying to change the path to %s\n", path );

    int i = chdir(path);
    if( i == 0 )
    {
        printf("sucess\n");
        if (getcwd(cwd, sizeof(cwd)) != NULL)
            fprintf(stdout, "Current working dir: %s\n", cwd);
        else
            perror("getcwd() error");
    }
    else
    {
        perror("Directory not changed: ");
    }
    return 0;
}

Кроме того, поскольку я разрабатываю оболочку, я сталкиваюсь с той же проблемой с другими командами, которые используют путь к файлу, например ls. Например, я получаю аналогичное сообщение для (когда есть пробелы, но путь правильный):

execvp("ls", path, NULL);

person Jenna Maiz    schedule 29.04.2016    source источник
comment
Когда вы вводите путь, вы вводите обратную косую черту перед пробелом? Если да, то не делайте этого.   -  person John Kugelman    schedule 29.04.2016


Ответы (1)


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

  1. Если вы вводите команду оболочки, например cd, оболочка интерпретирует командную строку и разделяет ее на неэкранированные пробелы. В вашем примере вы не хотите, чтобы ваше имя пути разделялось между Spring и 2016, поэтому вы избегаете этого пробела.

    Другими словами, оболочка превращает ваш /users/bayesianStudent/desktop/Spring\ 2016 в /users/bayesianStudent/desktop/Spring 2016, и это то, что поступает в программу.

  2. Если вы вводите путь в программу, как в

    printf("Please enter path:\n");
    gets(path);
    

    у вас нет побега, поэтому вам нужно ввести путь как есть. В частности, если вы введете /users/bayesianStudent/desktop/Spring\ 2016, ваша программа увидит строку, включающую \, и увидит, что такого каталога не существует.

person glglgl    schedule 29.04.2016