รู้สึกเหมือนคนงี่เง่าในขณะนี้ ทำไมสิ่งนี้ไม่ทำงาน
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'