การเลือกชื่อคำถามของคุณค่อนข้างสับสน
pushd
/ popd
, csh
คุณสมบัติที่คัดลอกโดยbash
และzsh
, เป็นวิธีจัดการสแต็คของไดเรกทอรีที่จำได้
pushd /some/dir
พุชไดเร็กทอรีการทำงานปัจจุบันลงบนสแต็กจากนั้นเปลี่ยนไดเร็กทอรีการทำงานปัจจุบัน (จากนั้นพิมพ์/some/dir
ตามด้วยเนื้อหาของสแต็กนั้น (คั่นด้วยช่องว่าง)
popd
พิมพ์เนื้อหาของสแต็ก (อีกครั้งคั่นด้วยช่องว่าง) จากนั้นเปลี่ยนเป็นองค์ประกอบด้านบนของสแต็กและปรากฏจากสแต็ก
(ระวังด้วยว่าบางไดเร็กทอรีจะถูกแสดงที่นั่นพร้อมกับ~/x
หรือ~user/x
หมายเหตุ)
ดังนั้นหากสแต็กปัจจุบันมี/a
และ/b
ไดเรกทอรีปัจจุบันคือ/here
และคุณกำลังทำงาน:
pushd /tmp/whatever
popd
pushd
จะพิมพ์/tmp/whatever /here /a /b
และการpopd
ส่งออกจะไม่/here /a /b
/tmp/whatever
ที่เป็นอิสระจากการใช้การทดแทนคำสั่งหรือไม่ popd
ไม่สามารถใช้เพื่อรับพา ธ ของไดเรกทอรีก่อนหน้าและโดยทั่วไปเอาต์พุตไม่สามารถประมวลผลการโพสต์ได้ (ดู$dirstack
หรือ$DIRSTACK
อาร์เรย์ของเชลล์บางตัวเพื่อเข้าถึงองค์ประกอบของสแต็กไดเรกทอรีนั้น)
บางทีคุณอาจต้องการ:
pushd "$(mktemp -d)" &&
popd &&
rmdir "$OLDPWD"
หรือ
cd "$(mktemp -d)" &&
cd - &&
rmdir "$OLDPWD"
แม้ว่าฉันจะใช้:
tmpdir=$(mktemp -d) || exit
(
cd "$tmpdir" || exit # in a subshell
# do what you have to do in that tmpdir
)
rmdir "$tmpdir"
ไม่ว่าในกรณีใดpushd "$(mktemp -d)"
ไม่ทำงานpushd
ใน subshell หากเป็นเช่นนั้นจะไม่สามารถเปลี่ยนไดเรกทอรีทำงานได้ นั่นคือmktemp
ที่ทำงานใน subshell เนื่องจากเป็นคำสั่งแยกต่างหากจึงต้องรันในกระบวนการแยกต่างหาก มันเขียนเอาต์พุตบนไพพ์และกระบวนการเชลล์อ่านมันที่ปลายอีกด้านของไพพ์
ksh93 สามารถหลีกเลี่ยงกระบวนการที่แยกต่างหากเมื่อคำสั่งถูกสร้างขึ้น แต่แม้จะมีก็ยังคงเป็น subshell (สภาพแวดล้อมการทำงานที่แตกต่างกัน) ซึ่งเวลานี้จะถูกจำลองขึ้นมาแทนที่จะอาศัยสภาพแวดล้อมที่แยกต่างหากตามปกติโดยการฟอร์ก ยกตัวอย่างเช่นในksh93
, a=0; echo "$(a=1; echo test)"; echo "$a"
ไม่มีส้อมมีส่วนเกี่ยวข้อง แต่ก็ยังเอาท์พุทecho "$a"
0
ที่นี่หากคุณต้องการเก็บเอาท์พุทของmktemp
ตัวแปรในเวลาเดียวกับที่คุณส่งมันไปpushd
ด้วยzsh
คุณสามารถทำได้:
pushd ${tmpdir::="$(mktemp -d)"}
กับกระสุนคล้ายบอร์นอื่น ๆ :
unset tmpdir
pushd "${tmpdir=$(mktemp -d)}"
หรือหากต้องการใช้เอาต์พุต$(mktemp -d)
หลายครั้งโดยไม่เก็บไว้ในตัวแปรอย่างชัดเจนคุณสามารถใช้zsh
ฟังก์ชั่นที่ไม่ระบุชื่อ:
(){pushd ${1?} && cd - && rmdir $1} "$(mktemp -d)"
trap
handler สามารถล้างไดเร็กทอรีได้หากโปรเซสถูกสัญญาณโดยสัญญาณ