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 ดีกว่าเพราะมันชี้ไปที่ "dir ตัวจริง" ไม่ใช่ลิงก์สัญลักษณ์ไปยัง oracle executable ... ซึ่งเป็นสาเหตุที่ผู้ประเมิน sed ของฉันล้มเหลว :)
Michael Mao

คำตอบ:


129

คุณใช้ไปป์ในกรณีที่คำสั่งต้องการพารามิเตอร์จากอินพุตมาตรฐาน ( เพิ่มเติมเกี่ยวกับเรื่องนี้ )

ด้วยcdคำสั่งที่ไม่เป็นเช่นนั้น ไดเร็กทอรีคืออาร์กิวเมนต์คำสั่ง ในกรณีนี้คุณสามารถใช้การทดแทนคำสั่ง ใช้ backticks หรือ$(...)ประเมินคำสั่งเก็บเป็นตัวแปร ..

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

แม้ว่าจะทำได้ง่ายกว่ามากก็ตาม:

cd `which oracle` 

หรือถ้าเส้นทางของคุณมีอักขระพิเศษ

cd "`which oracle`"

หรือ

cd $(which oracle)

ซึ่งเทียบเท่ากับสัญกรณ์ backtick แต่ขอแนะนำ (backticks อาจสับสนกับเครื่องหมายอะพอสทรอฟี)

.. แต่ดูเหมือนว่าคุณต้องการ:

cd $(dirname $(which oracle))

(ซึ่งแสดงให้คุณเห็นว่าคุณสามารถใช้การซ้อนได้อย่างง่ายดาย)

$(...) (เช่นเดียวกับ backticks) ยังทำงานในสตริงที่ยกมาสองครั้งซึ่งจะช่วยเมื่อผลลัพธ์อาจมีช่องว่างในที่สุด ..

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

(โปรดทราบว่าเอาต์พุตทั้งสองต้องมีชุดอัญประกาศคู่)


เย็น. คุณช่วยอธิบายเล็กน้อยเกี่ยวกับสิ่งที่เกิดขึ้นที่นี่ได้ไหม ที่ดูเหมือนการอ้างอิงตัวแปร มีตัวแปรชั่วคราวเริ่มต้นที่ผลลัพธ์ของคำสั่งไปหรือไม่?
Nate W.

อ๊ะฉันลืมนึกถึงเรื่องแบ็คติก :(
Michael Mao

4
คุณต้องการคำพูดคู่อื่น: cd "$(dirname "$(which oracle)")".
Philipp

|เปิดกระบวนการใหม่ดังนั้นแม้ว่าcdอ่านจาก STDIN, cmd | cdจะไม่ทำงาน (เช่นไดเรกทอรีปัจจุบันในกระบวนการเดิมจะยังคงเหมือนเดิม)
Kyle Strand

24

ด้วย dirname เพื่อรับไดเร็กทอรี:

cd $(which oracle | xargs dirname)

แก้ไข: ระวังเส้นทางที่มีช่องว่างโปรดดูความคิดเห็น @anishpatel ด้านล่าง


3
ใช้cd "$(which oracle | xargs -0 dirname)"หากเส้นทางอาจมีช่องว่าง แฟล็ก -0 แยกอินพุตด้วย null แทนที่จะเป็นช่องว่าง
anishpatel

9
cd `which oracle`

โปรดทราบว่าสิ่งเหล่านี้เป็นแบ็คทิก (โดยทั่วไปคือปุ่มทางด้านซ้ายของ 1 บนแป้นพิมพ์ของสหรัฐอเมริกา)


1
วิธีนี้จะใช้ไม่ได้หากเส้นทางมีช่องว่างหรืออักขระ "พิเศษ" อื่น ๆ และคุณต้องตัดชื่อไฟล์ออก
Philipp

@Philipp คุณสามารถใช้สิ่งนี้ได้หากเส้นทางของคุณมีอักขระพิเศษcd "`which oracle`"
Ram Patra

4

ตกลงนี่คือวิธีแก้ปัญหาที่ใช้การอ้างอิงที่ถูกต้อง:

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

หลีกเลี่ยงการ backticks พวกเขาอ่านได้น้อยและมักจะอ้างอิงการแทนที่กระบวนการ


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`)

วิธีนี้ใช้ไม่ได้หากเส้นทางมีช่องว่างหรืออักขระ "พิเศษ" อื่น ๆ
Philipp

1
แก้ไขได้อย่างง่ายดายโดยการอ้างซ้ำสองครั้ง
David Z

1

นอกเหนือจากคำตอบที่ดีข้างต้นสิ่งหนึ่งที่ต้องพูดถึงคือcdเป็นเชลล์ในตัวซึ่งทำงานในกระบวนการเดียวกันนอกเหนือจากกระบวนการใหม่เช่นlsซึ่งเป็นคำสั่ง

  1. /unix/50022/why-cant-i-redirect-a-path-name-output-from-one-command-to-cd

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.