Почему я не могу передать материал в CD?
Пример:
$ pwd >> ~/mloc
$ cd /
$ tail -n 1 ~/mloc | cd
CD не работает. Если сделать: cd $(tail -n 1 ~/mloc)
, это работает.
Я понимаю, что последняя команда, которую я написал, работает, но я не понимаю, почему я не могу перейти на CD.
Передача по трубопроводу процессу отправляет в него данные вместо того, что вы набрали бы после того, как вы запустили процесс, , а не , что вы ввели как часть команды, которая запускает процесс.
(cd
также не является процессом, но это менее важно, я рассмотрю его ниже.)
Трубопровод присоединяет вывод одной команды к другой команды вход . Рассмотрим:
foo | bar
, который запускает bar
, запускает foo
и:
bar
на терминале, он направляет его к foo
в качестве ввода. foo
с терминала , он получает его с выхода bar
. (Оба этих пункта обозначают одно и то же.)
Итак, что происходит, когда вы запускаете tail -n 1 ~/mloc | cd
?
cd
и всякий раз, когда cd
принимает входные данные во время работы, он принимает этот входной сигнал с выхода tail -n 1 ~/mloc
. cd
никогда не принимает ввод во время работы. См. стандартные потоки (Википедия) для получения дополнительной информации о точном значении ввода и вывода в этом ответе. (Здесь под вводом я подразумеваю «стандартный ввод», а под выводом - «стандартный вывод».)
Существует также проблема, заключающаяся в том, что cd
на самом деле не программа, а встроенная оболочка, поэтому когда вы запускаете cd
, новый процесс не запускается. Но это не на самом деле , почему то, что вы пытаетесь, не работает, потому что:
Нет никакой причины, по которой оболочка не может быть написана для размещения труб - встроенной оболочки, учитывая, что они содержат трубы из встроенных оболочек.
Обратите внимание, что иногда, когда вы используете встроенную оболочку, похожую на настоящую программу, вместо этого запускается настоящая программа с тем же именем. Но для cd
нет отдельной программы, и мы можем передать из cd
; например, запустите cd blah 2>&1 | less
; если blah
не существует или не является каталогом, вы сможете просмотреть ошибку в less
.
Наконец, рассмотрим, что отличается от cd $(tail -n 1 ~/mloc)
. Эта команда:
tail -n 1 ~/mloc
и захватывает ее вывод. cd
. Короткий ответ: CD не работает так.
http://www.gnu.org/software/bash/manual/bashref.html#index-cd
Более длинный ответ - в bash команды в конвейере каждый выполнен в подоболочке. Поскольку cd является встроенной оболочкой, он влияет только на оболочку, в которой он выполняется. Если вы перейдете в подоболочку, эффект исчезнет при выходе из подоболочки.