Unix: (теперь pwd: ~) из команды cd?

Будучи собой, я поигрался с терминалом (zsh.) Одна из вещей, которые я пробовал (в пустом каталоге), была mkdir test; ls | cd Это должно создать папку, а затем распечатать все папки (так что только эта ) и передать вывод на cd. Поэтому я ожидал, что он приведет меня в тестовый каталог, но вместо этого я получил (pwd now: ~), и он вернул меня в домашний каталог. Кто-нибудь знает, почему это так? Поиск ничего полезного не дает.

РЕДАКТИРОВАТЬ: Это приводит меня в каталог ~, потому что cd не принимает ввод stdin, а скорее каталог является аргументом. Что я все еще хочу знать, так это то, почему запуск ls | cd дает результат (pwd now: ~), а не просто ничего. Запуск echo test | cd не дает выходных данных, но ls | cd дает.


person 5ynt4x_3rr0r_    schedule 24.08.2020    source источник
comment
Отвечает ли это на ваш вопрос? bash - как передать результат команды what на компакт-диск   -  person joshmeranda    schedule 24.08.2020
comment
Нет, я искал, почему он выдает именно (pwd now: ~) вывод, а не как сделать так, чтобы он не выдавал этот вывод.   -  person 5ynt4x_3rr0r_    schedule 24.08.2020


Ответы (1)


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

# 2 process are run here
# first job: echo
# second job: ls
echo "/home/" | ls

Глядя на источник для zsh, похоже, что cwd задания отличается от оригинала. cwd задания после выполнения он уведомит пользователя сообщением типа (pwd now: foo). Это помогает гарантировать, что пользователь точно знает, где они находятся в дереве каталогов, что особенно полезно, когда он, возможно, не собирался этого делать. Ниже взято из jobs.c, где cwd (обозначается как pwd), где, среди прочего, cwd (обозначается как pwd) сравниваются перед печатью сообщения (pwd now: foo). Если они разные, сообщение печатается, если равны - нет.

if ((lng & 4) || (interact && job == thisjob &&
              jn->pwd && strcmp(jn->pwd, pwd))) {
    doneprint = 1;
    fprintf(fout, "(pwd %s: ", (lng & 4) ? "" : "now");
    fprintdir(((lng & 4) && jn->pwd) ? jn->pwd : pwd, fout);
    fprintf(fout, ")\n");
    fflush(fout);
    }

Когда вы передаете что-то в ch, вы изменяете cwd в дочернем процессе, и некоторые из обычных проверок, которые скрывают это сообщение при прямом вызове cd, обходят стороной. В противном случае cd слов таким же образом.

# changes directories into ./test
echo "test" | cd
# (pwd now: /path/to/test)

# changes directory to home
echo | cd
# (pwd now: /home/<username>)

# calling this again will not echo the message, since the cwd is already
# the home directory and no change occurs 
echo | cd

Что касается того, почему cwd изменяется на домашний каталог (~), это связано с тем, как ведет себя cd, когда в качестве аргумента не указаны пути. В отличие от многих команд Linux, cd не считывает из stdin пути для перехода. Из-за этого конвейер в cd просто заполнит stdin вместо cd, но это содержимое будет проигнорировано. Из-за этого передача в cd аналогична простому вызову cd.

# these next lines produce the same behavior
echo path/to/dir/test | cd
cd

Когда cd не получает путь для перехода, он переместит вас в ваш домашний каталог (обозначается в системах Linux как ~)

# each of these lines produce the same behavior
cd /home/<username>
cd ~
cd
person joshmeranda    schedule 24.08.2020
comment
так почему cd выдает вывод (pwd now: ~), когда я передаю в него текст из ls? Он не дает такого результата, когда я делаю echo test | cd или просто cd, но дает, когда я делаю ls | cd. - person 5ynt4x_3rr0r_; 26.08.2020
comment
Это похоже на специфическое поведение оболочки, я не смог воспроизвести его на fish, bash или sh. Какую оболочку и какую версию используете? - person joshmeranda; 26.08.2020
comment
Я использую zsh, потому что bash сказал мне использовать его - person 5ynt4x_3rr0r_; 26.08.2020
comment
О, хорошо, это похоже на вывод, специфичный для реализации zsh или обработки процесса. Позвольте мне взглянуть на это, и я обновлю свой ответ - person joshmeranda; 26.08.2020
comment
Я добавил неглубокое объяснение основной причины сообщения из того, что я могу почерпнуть из источника. Я приветствую любой вклад от тех, кто более вовлечен в его разработку или знаком с zsh внутренней работой. - person joshmeranda; 26.08.2020
comment
Отличный ответ. Я пришел сюда, потому что пытался ls -a | grep mydir | cd (пытался cd превратить в /mydir. В любом случае, я просто хотел убедиться, что ничего случайно не удалил. Похоже, это безвредно - person stevec; 10.02.2021