bash - cara menyalurkan hasil dari perintah which ke cd

87

Bagaimana saya bisa menyalurkan hasil dari whichperintah ke cd?

Inilah yang saya coba lakukan:

which oracle | cd
cd < which oracle

Tapi tidak satupun dari mereka berhasil.

Apakah ada cara untuk mencapai ini (daripada salin / tempel tentu saja)?

Edit: setelah dipikir-pikir, perintah ini akan gagal, karena file tujuan BUKAN folder / direktori .

Jadi saya berpikir dan mencari cara yang lebih baik untuk menyingkirkan bagian trailing "/ oracle" sekarang (sed atau awk, atau bahkan Perl) :)

Sunting: Oke itulah yang saya dapatkan pada akhirnya:

cd `which oracle | sed 's/\/oracle//g'`
Michael Mao
sumber
2
yang memberi Anda perintah, bukan direktori
Anycorn
apakah Anda mencoba mendapatkan direktori tempat program diinstal? dirname, basename ?
Anycorn
@aaa: Anda benar, saya pikir dirname lebih baik karena menunjuk ke "the real dir" bukan tautan simbolis ke oracle yang dapat dieksekusi ... itulah sebabnya sed apporach saya akan gagal :)
Michael Mao

Jawaban:

129

Anda menggunakan pipa dalam kasus di mana perintah mengharapkan parameter dari input standar. ( Lebih lanjut tentang ini ).

Dengan cdperintah itu tidak terjadi. Direktori adalah argumen perintah. Dalam kasus seperti itu, Anda dapat menggunakan substitusi perintah. Gunakan backticks atau $(...)untuk mengevaluasi perintah, simpan ke dalam variabel ..

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

meskipun itu bisa dilakukan dengan cara yang jauh lebih sederhana:

cd `which oracle` 

atau jika jalur Anda memiliki karakter khusus

cd "`which oracle`"

atau

cd $(which oracle)

yang setara dengan notasi backtick, tetapi disarankan (backtick bisa disalahartikan dengan apostrof)

.. tapi sepertinya Anda menginginkan:

cd $(dirname $(which oracle))

(yang menunjukkan bahwa Anda dapat menggunakan bersarang dengan mudah)

$(...) (serta tanda kutip) juga dapat digunakan dalam string yang dikutip ganda, yang membantu saat hasil akhirnya mungkin berisi spasi ..

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

(Perhatikan bahwa kedua keluaran membutuhkan satu set tanda kutip ganda.)

mykhal
sumber
Keren. Bisakah Anda menjelaskan sedikit tentang apa yang terjadi di sini? Itu terlihat seperti dereferensi variabel; apakah ada beberapa variabel sementara default di mana hasil perintah pergi?
Nate W.
Ahhh, saya lupa compelete tentang backticks :(
Michael Mao
4
Anda perlu sepasang tanda kutip: cd "$(dirname "$(which oracle)")".
Philipp
Ini |membuka proses baru, jadi meskipun cdmembaca dari STDIN, cmd | cdtidak akan berfungsi (yaitu direktori saat ini dalam proses asli akan tetap sama).
Kyle Strand
23

Dengan dirname untuk mendapatkan direktori:

cd $(which oracle | xargs dirname)

EDIT: berhati-hatilah dengan jalur yang berisi spasi, lihat komentar @anishpatel di bawah


sumber
2
Gunakan cd "$(which oracle | xargs -0 dirname)"jika jalur mungkin berisi spasi. Bendera -0 membagi input dengan null, bukan spasi.
anishpatel
9
cd `which oracle`

Perhatikan bahwa itu adalah backticks (umumnya tombol di sebelah kiri 1 pada keyboard AS)

Cfreak
sumber
1
Ini tidak berfungsi jika jalur berisi spasi atau karakter "khusus" lainnya, dan Anda harus menghapus nama file.
Philipp
@Philipp Anda dapat menggunakan ini jika jalur Anda memiliki karakter khususcd "`which oracle`"
Ram Patra
4

Oke, berikut solusi yang menggunakan kutipan yang benar:

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

Hindari backticks, mereka kurang terbaca, dan selalu mengutip proses substitusi.

Philipp
sumber
2

Anda tidak memerlukan pipa, Anda dapat melakukan apa yang Anda inginkan menggunakan perluasan parameter Bash!

Tip lebih lanjut: gunakan "type -P" daripada perintah eksternal "which" jika Anda menggunakan 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
bashfu
sumber
1

Sebagai tanggapan atas pertanyaan yang Anda edit, Anda dapat menghapus nama perintah menggunakan dirname:

cd $(dirname `which oracle`)
David Z
sumber
Ini tidak berfungsi jika jalur berisi spasi atau karakter "khusus" lainnya.
Philipp
1
Mudah diperbaiki dengan mengutip dua kali.
David Z