используя xargs для перехода в каталог


28

Чувствую себя идиотом прямо сейчас. Почему это не работает?

echo "/some/directory/path" | xargs -n1 cd

Ответы:


22

Канал запускает xargs в подпроцессе, а xargs запускает cd в подпроцессе. Изменения в подпроцессе не распространяются на родительский процесс.


Это имеет полный смысл. Спасибо за помощь Unix Noob.
Ян Лотинский

3
Вы можете получить cd `echo "/some/directory/path" | cut -d\ -f1` желаемый эффект, используя обратные кавычки: (Обратите внимание, что я добавил 'cut', чтобы разделить пробелы и захватить первый элемент, как это делает xargs)
Slartibartfast

5
На самом деле, xargsне может работать, cdтак как это, по необходимости, встроенная оболочка и xargsможет запускать только автономные исполняемые файлы. Однако то, что вы сказали, верно в отношении подпроцессов.
Приостановлено до дальнейшего уведомления.

/ usr / bin / cd - определенно автономная документированная команда Unix, по крайней мере в Solaris.
2010 года

Использование @Slartibartfast для автоматически сгенерированных путей: cd `port file libcudd | sed -e 's/\/Portfile//'` (как правило, длинные, которые вы не хотите обрабатывать вручную, например, это расположение файла портов MacPorts).
Иоаннис Филиппидис

23

Команда cdявляется встроенной, поскольку информация о текущем каталоге связана с процессом, и только встроенная оболочка может изменить текущий каталог запущенной оболочки.

Есть две проблемы с вашим кодом:

  1. xargsне может работать, cdпотому что cdэто встроенная команда и xargsможет запускать только исполняемые файлы.
  2. Даже если вы выполняете cdподпроцесс, вызванный из xargs, он не окажет никакого влияния на родительский процесс, как описано выше.

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

ls | xargs -L 1 bash -c 'cd "$0" && pwd && ls'

Это не имеет смысла делать ls | xargs ...в этом примере. Должно быть указано значение для $0вроде:echo "/some/directory/path" | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
wisbucky

ИМО лучшим решением было бы: ls | xargs -L 1 -I @@ bash -c 'cd @@ && pwd && ls'
Роман М
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.