PS1 = '$ (pwd)' ทำไมมันถึงใช้งานได้และทำไมมันถึงแตกต่างจาก PS1 = $ (pwd)


18

เหตุใดเมื่อฉันป้อนคำสั่งนี้พรอมต์จึงเปลี่ยนไดเรกทอรีของฉัน

PS1='$(pwd)'

ฉันกำลังใช้เครื่องหมายคำพูดเดี่ยวซึ่งหมายถึงไม่มีการแก้ไขอาคาecho '$(pwd)'—— →$(pwd)

ยิ่งไปกว่านั้นบอกว่าเราชี้แจงว่าทำไมสิ่งนี้ถึงได้ผล ... ทำไมมันถึงแตกต่างจากเดิมPS1=$(pwd)? (ไม่มีเครื่องหมายคำพูดเลย)

โดยที่แตกต่างกันฉันหมายความว่าถ้าฉันใช้อัญประกาศแล้วพรอมต์จะเปลี่ยนไปยังไดเรกทอรีปัจจุบันของฉันในขณะที่ฉันนำทางผ่านสถานี แต่ถ้าฉันไม่ใช้เครื่องหมายคำพูดแล้วพรอมต์จะยังคงอยู่ในไดเรกทอรีที่ฉันอยู่เมื่อฉันป้อนคำสั่งครั้งแรกPS1=$(pwd)

ทำไม?


2
บันทึก CPU รอบและใช้เทียบเท่า PS1 = '$ PWD'
jlliagre

คำตอบ:


29

เมื่อคุณกำหนดค่าให้กับตัวแปรเพียง$(...)นิพจน์จะถูกประเมินค่าเว้นแต่จะอยู่ในเครื่องหมายคำพูดเดี่ยว (หรือเครื่องหมายแบ็กสแลชที่ใช้ Escape) เพื่อความเข้าใจลองและเปรียบเทียบสองสิ่งนี้:

A=$(pwd)
echo "$A"
B='$(pwd)'
echo "$B"

ค่าของAสตริงจะกลายเป็นสตริงทันที/home/yourusernameและแน่นอนว่ามันไม่ถูกจดจำว่าสตริงนี้มาจากไหนมันจะยังคงเหมือนเดิมแม้ว่าคุณจะเปลี่ยนไดเรกทอรี อย่างไรก็ตามค่าของBกลายเป็นสตริงตัวอักษร$(pwd)โดยไม่ต้องตีความ

ตอนนี้ในคุณค่าของPS1สิ่งที่เกิดขึ้นเป็นพิเศษ: เมื่อใดก็ตามที่พิมพ์พรอมต์จะมีการแปลโครงสร้างพิเศษบางอย่างเช่นการแทนที่คำสั่ง$(...)จะดำเนินการอย่างที่มันเกิดขึ้นด้านบนเมื่อกำหนดให้กับAตัวแปร เห็นได้ชัดว่าถ้าคุณPS1มีสตริงตัวอักษรของไดเรกทอรีบ้านของคุณ (ดังกล่าวข้างต้นด้วยA) แล้วมันไม่มีทางที่จะเปลี่ยนแปลง แต่ถ้ามันมีสตริง$(pwd)(ดังกล่าวข้างต้นด้วยB) ก็จะถูกประเมินทุกครั้งที่มีการแจ้งให้พิมพ์และด้วยเหตุนี้ไดเรกทอรีที่แท้จริงของคุณจะปรากฏขึ้น


14

ในทั้ง bash และ zsh ค่าของPS1ไม่ถูกใช้เป็นพร้อมต์ตามที่เป็นมันผ่านการขยายบางส่วน กฎระเบียบที่แตกต่างกันสำหรับทั้งสองหอย แต่ในทั้งสองกรณีหนึ่งของขั้นตอนคือการดำเนินการ“ดอลลาร์” ขยาย (เปลี่ยนตัวตัวแปรแทนคำสั่งและการประเมินผลทางคณิตศาสตร์) มีไวยากรณ์เช่นเดียวกับในไวยากรณ์เปลือกปกติ ( , , หรือ$VARIABLE${VARIABLE}$(COMMAND)`COMMAND` , , ) .$((EXPRESSION))$[EXPRESSION]

  • ในทุบตีการขยายตัวของเงินดอลลาร์จะเปิดตามค่าเริ่มต้น แต่สามารถปิดได้ด้วย shopt -u promptvarsแต่สามารถปิดได้ด้วย
  • ใน zsh การขยายดอลลาร์จะปิดตามค่าเริ่มต้น แต่หลาย ๆ คน (และกรอบการกำหนดค่าส่วนใหญ่ที่คุณจะพบบนเว็บ) เปิดใช้งานด้วย setopt prompt_substเปิดด้วย

เมื่อเปิดใช้งานการขยายดอลลาร์ในพรอมต์ให้PS1='$(pwd)'ตั้งค่าPS1เป็น 6 ตัวอักษร$(pwd)และทำให้เกิด$(pwd)การแทนที่ดังนั้นจึงpwdต้องดำเนินการคำสั่งทุกครั้งที่เชลล์แสดงพรอมต์ใหม่ ในทางกลับกันการPS1=$(pwd)ตั้งค่าPS1เป็นไดเรกทอรีการทำงานปัจจุบันของเชลล์ในเวลาใดก็ได้ ถ้าคุณได้การขยายตัวของเงินดอลลาร์ปิดแล้วจะทำให้เกิดพร้อมที่จะเป็นสตริงตัวอักษรPS1='$(pwd)'$(pwd)

โปรดทราบว่ามีวิธีที่สะดวกกว่าในการรับไดเร็กทอรีการทำงานในพร้อมต์:

  • ในทุบตีด้วยการใช้แบ็กสแลชเช่น\wซึ่ง abbreviates ไดเรกทอรีบ้านของคุณไปและอาจถูกตัดออกจากการตั้งค่า~PROMPT_DIRTRIM
  • ใน zsh โดยมีเปอร์เซนต์การหลบหนีเช่น%/หรือ%~ (%/เป็นเช่นเดียวกับ$PWD, %~abbreviates ไดเรกทอรีบ้าน) ซึ่งจะมีการตั้งค่าการตัดแต่ง
  • ในเชลล์ (และเชลล์สไตล์บอร์นอื่น ๆ ) $PWDเทียบเท่ากับ$(pwd): คุณไม่จำเป็นต้องเรียกใช้กระบวนการย่อยเพื่อรับไดเรกทอรีการทำงานปัจจุบัน

7

เนื่องจากไม่มีเครื่องหมายคำพูดจะมีการประเมิน $ (pwd) เมื่อตั้งค่า PS1 ด้วยเครื่องหมายคำพูดการประเมินผลของ $ (pwd) จะถูกเลื่อนออกไปจนกว่าจะมีข้อความแจ้งปรากฏขึ้น

หากไม่มีเครื่องหมายอัญประกาศ PS1 จะถูกตั้งค่าเป็นไดเรกทอรีปัจจุบัน ณ เวลาที่มีการตั้งค่า PS1 ด้วยเครื่องหมายคำพูดเดี่ยว PS1 ถูกตั้งค่าเป็น $ (pwd) ซึ่งหมายความว่าจะประเมินและพิมพ์ไดเรกทอรีปัจจุบันทุกครั้งที่มีการแจ้งเตือน

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