มันจะดีกว่าถ้าใช้ $ (pwd) หรือ $ PWD?


35

ฉันพบBASEDIR=$(pwd)ในสคริปต์

มีข้อดีหรือข้อเสียมากกว่าการใช้BASEDIR="$PWD"นอกจากนั้น$PWDอาจถูกเขียนทับหรือไม่?


3
ข้อมูลบางอย่างที่unix.stackexchange.com/a/79621
Stéphane Chazelas

@ StéphaneChazelasเป็นบทความที่น่าสนใจมาก ฉันแค่ผ่านไปครึ่งทางและจะดำเนินการต่อไป แต่เท่าที่ฉันเข้าใจมันจะดีกว่าที่จะใช้$(pwd)เพราะ$PWDสามารถล้าสมัยในบางสถานการณ์
Minix

2
เฉพาะในเชลล์บางตัว (ไม่ใช่ bash, dash, zsh หรือ ksh93 เป็นต้น) pwdอาจให้ข้อมูลเก่าแก่คุณน้อยกว่า$PWDในบางกรณี $(pwd)ในทางกลับกันจะไม่ทำงานหากไดเรกทอรีปัจจุบันลงท้ายด้วยอักขระขึ้นบรรทัดใหม่หมายถึงการฟอร์กกระบวนการ (ยกเว้นใน ksh93) และใช้ทรัพยากรเพิ่มเติม มุมมองของฉันคือการใช้งาน$PWDของมันไม่คุ้มค่าใช้$(pwd -P) $(pwd)
Stéphane Chazelas

1
cd -P -- "$dir"ที่ด้านล่างมีสเตฟานกล่าวถึงการใช้ หากมีข้อสงสัยเกี่ยวกับคุณค่าของ$PWDคุณสามารถเสมอcd -P .ก่อน สิ่งนี้อาจเป็นประโยชน์ในการที่คุณได้รับสิ่งที่$PWDเคยเป็นมาก่อนใน$OLDPWDและเพื่อให้สามารถเปรียบเทียบพวกเขาในภายหลัง - และcd ...; cd -ลำดับต่อไปจะต้องแน่ใจว่าจะนำคุณกลับไปที่ที่คุณอยู่ตอนนี้
mikeserv

คำตอบ:


41

หาก bash พบ$(pwd)มันจะรันคำสั่ง pwd และแทนที่$(pwd)ด้วยเอาต์พุตของคำสั่งนี้ $PWDเป็นตัวแปรที่ตั้งค่าไว้เกือบตลอดเวลา pwd เป็นคำสั่ง builtin shell มาเป็นเวลานาน

ดังนั้น$PWDจะล้มเหลวหากไม่ได้ตั้งค่าตัวแปรนี้และ$(pwd)จะล้มเหลวหากคุณใช้เชลล์ที่ไม่สนับสนุน$()โครงสร้างซึ่งเป็นประสบการณ์ของฉันบ่อยครั้งในกรณี $PWDดังนั้นผมจะใช้

ในฐานะ nerd ทุกคนฉันมีบทช่วยสอนการเขียนสคริปต์เชลล์ของตัวเอง


6
ฉันอยู่ภายใต้การแสดงผลที่`command`ไวยากรณ์ไม่พึงประสงค์และ$(command)เป็นที่ต้องการ เท่าที่ฉันรู้ว่าหลังเป็นไปตาม POSIX แต่ฉันไม่แน่ใจ 100%
Minix

6
@ Minix การ$()ระบุแน่นอนโดย POSIX ดังนั้นก่อน POSIX ที่/bin/shมีอยู่บน Solaris 10 และcshเชลล์ที่เก่ากว่าและที่ได้รับฉันสงสัยว่าเชลล์หลักอื่น ๆ จำนวนมากขาดคุณสมบัติดังกล่าว
jlliagre

@Minix: นี่เป็นคำถามเมื่อเร็ว ๆ นี้ในเว็บไซต์นี้ที่แสดงให้เห็นถึงปัญหาอย่างหนึ่งเกี่ยวกับการใช้ backticks แทน$()
PM 2Ring

ถูกต้องแทน $ () คุณสามารถใช้ backticks ได้ แต่สิ่งนี้จะไม่เป็นปัญหาดังนั้นฉันจึงไม่ได้พูดถึงมัน
Thorsten Staerk

1
แผนที่
ย่อ

6

ควรกล่าวถึงว่า$PWDเป็นที่ต้องการเนื่องจากประสิทธิภาพของมัน ในฐานะตัวแปรเชลล์สามารถแก้ไขได้เกือบจะในทันที $(pwd)ค่อนข้างสับสนอีกนิด หากคุณตรวจสอบman 1 bulitinระบบด้วย Bash คุณจะเห็นว่าpwdเป็นคำสั่งในตัวซึ่งอาจทำให้คุณเชื่อว่ามันจะเร็วพอ ๆ กับการเข้าถึงตัวแปร อย่างไรก็ตาม$()โครงสร้างจะเปิดใช้เชลล์ย่อยใหม่ (กระบวนการใหม่) เสมอเพื่อเรียกใช้เนื้อหาโดยไม่คำนึงถึงสิ่งที่อยู่ภายใน สิ่งเดียวกันสำหรับ backticks แน่นอนเมื่อฉันมาตรฐาน:

echo 'Benchmarking $(pwd)...'
time (for i in {1..1000}; do echo $(pwd) > /dev/null; done)
echo 'Benchmarking $PWD...'
time (for i in {1..1000}; do echo $PWD > /dev/null; done)

ฉันได้รับ 1.52 วินาทีสำหรับการ$(pwd)โทรและ 0.018 วินาทีสำหรับการ$PWDโทร การเปิดใช้ subshells ที่ไม่จำเป็นรวมถึงกระบวนการภายนอกอื่น ๆ นั้นควรหลีกเลี่ยงเมื่อทำได้ ราคาแพงกว่าฟังก์ชั่นการโทรที่คุณอาจคุ้นเคยในภาษาอื่น


นั่นเป็นสิ่งที่น่าสนใจ แต่ฉันไม่รู้ว่าฉันกังวลเกี่ยวกับการทำงานกับเชลล์สคริปไหม ฉันยังสงสัยว่าประสิทธิภาพจะเปลี่ยนไปอย่างไรถ้า pwd เปลี่ยนแปลงระหว่างการสอบถาม
Minix

@ Minix ฉันปรับเปลี่ยนสคริปต์ของฉันเพื่อให้ลูปบอดี้เป็นecho $PWD; pushd ..; echo $PWD; popd(โดยเพิ่มเติม>/dev/nullหลังจากแต่ละคำสั่ง) และใช้เวลา 0.05 วินาที ฉันลบคำสั่ง echo ออก (pushd / popd เท่านั้น) และใช้เวลา 0.03 ดังนั้นเวลาต่อecho $PWDยังคงเป็น 0.01 วินาทีหรือมากกว่านั้น ฉันทำสิ่งที่คล้ายกัน$(pwd)และใช้เวลา 2.2 วินาทีต่อการวนซ้ำดังนั้น 1.1 วินาทีต่อการ$(pwd)โทร
markasoftware

เพื่อไม่ให้จู้จี้จุกจิกเกินไป แต่ฉันสามารถจินตนาการได้ว่าการคำนวณที่จะเข้ามาแทนที่จะ$PWDต้องทำในพื้นหลังก่อนการประเมินผลของคำสั่ง echo แต่ชัดเจนว่าการเข้าถึง$PWDยังเร็วกว่าอย่างมากดังนั้นหากความเข้ากันได้ไม่ได้เป็นปัญหานี่คือเหตุผลที่เลือกอย่างหนึ่ง ขอขอบคุณที่ทำงานทดสอบนี้อย่างละเอียดถี่ถ้วน :)
Minix
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.