bash - як конвеювати результат з якої команди на 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 краще, оскільки воно вказує на "справжній каталог", а не на символічне посилання на виконуваний файл оракула ... саме тому мій 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не працюватиме (тобто поточний каталог в первісному процесі буде залишатися такою ж).
Kyle Strand,

23

З dirname, щоб отримати каталог:

cd $(which oracle | xargs dirname)

EDIT: остерігайтеся шляхів, що містять пробіли, див. Коментар @anishpatel нижче


2
Використовуйте, cd "$(which oracle | xargs -0 dirname)"якщо шлях може містити пробіли. Прапор -0 розділяє введення за нулем, а не за пробілами.
анішпатель

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.