รู้สึกเหมือนคนงี่เง่าในขณะนี้ ทำไมสิ่งนี้ไม่ทำงาน
echo "/some/directory/path" | xargs -n1 cd
รู้สึกเหมือนคนงี่เง่าในขณะนี้ ทำไมสิ่งนี้ไม่ทำงาน
echo "/some/directory/path" | xargs -n1 cd
คำตอบ:
ไพพ์รัน xargs ในกระบวนการย่อยและ xargs รัน cd ในกระบวนการย่อย การเปลี่ยนแปลงในกระบวนการย่อยไม่ได้รับการเผยแพร่สู่กระบวนการหลัก
cd `echo "/some/directory/path" | cut -d\ -f1`
(โปรดทราบว่าฉันเพิ่ม 'ตัด' เพื่อแยกช่องว่างและหยิบรายการแรกตามที่ xargs ทำ)
xargs
ไม่สามารถรันได้cd
เพราะมันเป็นเชลล์ที่มีความจำเป็นและxargs
สามารถเรียกใช้โปรแกรมปฏิบัติการแบบยืนได้เท่านั้น อย่างไรก็ตามสิ่งที่คุณพูดนั้นเป็นความจริงเกี่ยวกับกระบวนการย่อย
cd `port file libcudd | sed -e 's/\/Portfile//'`
(โดยปกติจะยาวมากซึ่งคุณไม่ต้องการจัดการด้วยตนเองเช่นตำแหน่ง MacPorts Portfile)
คำสั่งcd
เป็นบิวด์อินเนื่องจากข้อมูลเกี่ยวกับไดเร็กทอรีปัจจุบันเชื่อมโยงกับกระบวนการและมีเพียงเชลล์บิวด์อินเท่านั้นที่สามารถเปลี่ยนไดเร็กทอรีปัจจุบันของเชลล์ที่กำลังรัน
รหัสของคุณมีปัญหาสองประการ:
xargs
ไม่สามารถเรียกใช้cd
เพราะcd
เป็นคำสั่งในตัวและxargs
สามารถเรียกใช้ไฟล์ที่ปฏิบัติการได้เท่านั้นcd
ในกระบวนการย่อยที่เรียกว่าxargs
มันจะไม่มีผลใด ๆ กับกระบวนการหลักดังที่อธิบายไว้ข้างต้นวิธีการแก้ปัญหาคือการเรียกใช้ sub-shell ภายในนั้นเรียกใช้cd
แล้วคุณสามารถรันคำสั่งในไดเรกทอรีปัจจุบันใหม่
ls | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
ls | xargs ...
ในตัวอย่างนี้ มันควรจะผ่านคุณค่า$0
เช่นecho "/some/directory/path" | xargs -L 1 bash -c 'cd "$0" && pwd && ls'