bash - как передать результат команды which на cd


87

Как я могу передать результат whichкоманды cd?

Вот что я пытаюсь сделать:

which oracle | cd
cd < which oracle

Но ни один из них не работает.

Есть ли способ добиться этого (вместо копирования / вставки, конечно)?

Изменить: если подумать, эта команда завершится ошибкой, потому что целевой файл НЕ является папкой / каталогом .

Итак, я думаю и разрабатываю лучший способ избавиться от конечной части "/ oracle" сейчас (sed или awk, или даже Perl) :)

Изменить: Хорошо, вот что у меня в итоге:

cd `which oracle | sed 's/\/oracle//g'`

2
что дает вам команду, а не каталог
Anycorn

вы пытаетесь получить каталог, в котором установлена ​​программа? dirname, basename ?
Anycorn

@aaa: вы правы, я думаю, что dirname лучше, потому что оно указывает на "настоящий каталог", а не на символическую ссылку на исполняемый файл oracle ... вот почему мой sed apporach не сработает :)
Майкл Мао,

Ответы:


128

Вы используете конвейер в случаях, когда команда ожидает параметры из стандартного ввода. ( Подробнее об этом ).

В случае с cdкомандой дело обстоит иначе. Каталог - это аргумент команды. В таком случае можно использовать подстановку команд. Используйте обратные кавычки или, $(...)чтобы оценить команду, сохраните ее в переменной ..

path=`which oracle`
echo $path # just for debug
cd $path

хотя это можно сделать и гораздо проще:

cd `which oracle` 

или если на вашем пути есть специальные символы

cd "`which oracle`"

или

cd $(which oracle)

что эквивалентно обозначению обратных кавычек, но рекомендуется (обратные кавычки можно спутать с апострофами)

.. но похоже, что вы хотите:

cd $(dirname $(which oracle))

(который показывает, что вы можете легко использовать вложение)

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

cd "$(dirname "$(which oracle)")"

(Обратите внимание, что для обоих выходов требуется набор двойных кавычек.)


Круто. Не могли бы вы немного объяснить, что здесь происходит? Это похоже на разыменование переменной; есть ли какая-то временная переменная по умолчанию, куда попадают результаты команды?
Nate W.

Аааа, я забыл о кавычках :(
Майкл Мао,

4
Вам нужно еще пару цитат: cd "$(dirname "$(which oracle)")".
Филипп

|Открывает новый процесс, так что даже если cdчитать из STDIN, cmd | cdне будет работать (т.е. текущий каталог в первоначальном процессе будет оставаться такой же).
Кайл Стрэнд

23

С dirname, чтобы получить каталог:

cd $(which oracle | xargs dirname)

EDIT: остерегайтесь путей, содержащих пробелы, см. Комментарий @anishpatel ниже


2
Используйте, cd "$(which oracle | xargs -0 dirname)"если путь может содержать пробелы. Флаг -0 разделяет ввод на ноль, а не на пробел.
анишпател 04

9
cd `which oracle`

Обратите внимание, что это обратные кавычки (обычно клавиша слева от 1 на американской клавиатуре)


1
Это не работает, если путь содержит пробелы или другие «специальные» символы, и вы должны удалить имя файла.
Филипп

@Philipp, вы можете использовать это, если на вашем пути есть специальные символыcd "`which oracle`"
Рам Патра

4

Хорошо, вот решение, использующее правильное цитирование:

cd "$(dirname "$(which oracle)")"

Избегайте обратных кавычек, они менее читабельны и всегда заключают в кавычки замены процесса.


2

Канал вам не нужен, вы можете делать все, что хотите, используя расширение параметров Bash!

Дополнительный совет: используйте «type -P» вместо внешней команды «which», если вы используете Bash.

# test
touch /ls
chmod +x /ls
cmd='ls'
PATH=/:$PATH
if cmdpath="$(type -P "$cmd")" && cmdpath="${cmdpath%/*}" ; then
   cd "${cmdpath:-/}" || { echo "Could not cd to: ${cmdpath:-/}"; exit 1; }
else
   echo "No such program in PATH search directories: ${cmd}"
   exit 1
fi

1

В ответ на ваш отредактированный вопрос вы можете удалить имя команды, используя dirname:

cd $(dirname `which oracle`)

Это не работает, если путь содержит пробелы или другие «специальные» символы.
Филипп

1
Легко исправить, заключив его в двойные кавычки.
David Z

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.