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

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

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

which oracle | cd
cd < which oracle

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

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

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

Поэтому я думаю и разрабатываю лучший способ избавиться от завершающей части «/ oracle» сейчас (sed или awk, или даже Perl) :)

Редактировать: Хорошо, вот что у меня получилось:

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

person Michael Mao    schedule 09.08.2010    source источник
comment
который дает вам команду, а не каталог   -  person Anycorn    schedule 09.08.2010
comment
Вы пытаетесь получить каталог, в котором установлена ​​программа? dirname, basename ?   -  person Anycorn    schedule 09.08.2010
comment
@aaa: вы правы, я думаю, что имя каталога лучше, потому что оно указывает на настоящий каталог, а не на символическую ссылку на исполняемый файл оракула ... вот почему мой sed apporach потерпит неудачу :)   -  person Michael Mao    schedule 09.08.2010


Ответы (7)


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

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

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

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

cd `which oracle` 

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

cd "`which oracle`"

or

cd $(which oracle)

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

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

cd $(dirname $(which oracle))

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

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

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

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

person mykhal    schedule 09.08.2010
comment
Прохладный. Не могли бы вы немного объяснить, что здесь происходит? Это похоже на разыменование переменной; есть ли какая-то временная переменная по умолчанию, куда попадают результаты команды? - person Nate W.; 09.08.2010
comment
Аааа, я забыл compelete про обратные кавычки :( - person Michael Mao; 09.08.2010
comment
Вам нужна еще пара кавычек: cd "$(dirname "$(which oracle)")". - person Philipp; 09.08.2010
comment
| открывает новый процесс, поэтому, даже если cd будет читать из STDIN, cmd | cd не будет работать (т. е. текущий каталог в исходном процессе останется прежним). - person Kyle Strand; 03.04.2014

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

cd $(which oracle | xargs dirname)

РЕДАКТИРОВАТЬ: остерегайтесь путей, содержащих пробелы, см. комментарий @anishpatel ниже

person Community    schedule 09.08.2010
comment
Используйте cd "$(which oracle | xargs -0 dirname)", если путь может содержать пробелы. Флаг -0 разделяет ввод на нуль, а не на пробел. - person anishpatel; 05.05.2017

cd `which oracle`

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

person Cfreak    schedule 09.08.2010
comment
Это не работает, если путь содержит пробелы или другие специальные символы, и вам нужно удалить имя файла. - person Philipp; 09.08.2010
comment
@Philipp, вы можете использовать это, если ваш путь содержит специальные символы cd "`which oracle`" - person Ram Patra; 09.07.2016

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

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

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

person Philipp    schedule 09.08.2010

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

Еще один совет: используйте «type -P» вместо внешней команды «what», если вы используете 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
person bashfu    schedule 09.08.2010

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

cd $(dirname `which oracle`)
person David Z    schedule 09.08.2010
comment
Это не работает, если путь содержит пробелы или другие специальные символы. - person Philipp; 09.08.2010
comment
Легко исправить двойным цитированием. - person David Z; 09.08.2010

Помимо хорошего ответа выше, необходимо упомянуть одну вещь: cd — это встроенная оболочка, которая запускается в том же процессе, что и новый процесс, такой как ls, который является командой.

  1. https://unix.stackexchange.com/questions/50022/why-cant-i-redirect-a-path-name-output-from-one-command-to-cd

  2. http://en.wikipedia.org/wiki/Shell_builtin

person Jiacai Liu    schedule 24.08.2014