ความแตกต่างที่แปลกประหลาดระหว่าง pwd และ / bin / pwd


15

ฉันเพิ่ม symlink ln -s . aaไปยังไดเรกทอรีปัจจุบันด้วย ถ้าผมดำเนินการcd aaและหลังจากที่ผมดำเนินการตอบสนองคือpwd/home/sim/aa

แต่ถ้าฉันรัน/bin/pwdมันจะพิมพ์/home/sim(ไดเรกทอรีปัจจุบันไม่เปลี่ยนแปลง)

ความแตกต่างนี้มาจากไหน?

คำตอบ:


17

ในเชลล์ส่วนใหญ่รวมถึง bash pwdคือเชลล์บิวด์อิน:

$ type -a pwd
pwd is a shell builtin
pwd is /bin/pwd

หากคุณใช้/bin/pwdคุณต้องใช้-Lตัวเลือกเพื่อให้ได้ผลลัพธ์เช่นเดียวกับ builtin pwd:

$ ln -s . test
$ cd test && pwd
/home/cuonglm/test
$ /bin/pwd
/home/cuonglm
$ /bin/pwd -L
/home/cuonglm/test

โดยค่าเริ่มต้น/bin/pwdละเว้นลิงค์และพิมพ์ไดเรกทอรีจริง

จากinfo pwd:

`-L'
`--logical'
     If the contents of the environment variable `PWD' provide an
     absolute name of the current directory with no `.' or `..'
     components, but possibly with symbolic links, then output those
     contents.  Otherwise, fall back to default `-P' handling.

`-P'
`--physical'
     Print a fully resolved name for the current directory.  That is,
     all components of the printed name will be actual directory
     names--none will be symbolic links.

บิวด์อินpwdรวม symlink โดยค่าเริ่มต้นยกเว้น-Pตัวเลือกที่ใช้หรือ-o physicalตั้งค่า builtin

จากman bash:

pwd [-LP]
              Print the absolute pathname of the  current  working  directory.
              The pathname printed contains no symbolic links if the -P option
              is supplied or the -o physical option to the set builtin command
              is  enabled.  If the -L option is used, the pathname printed may
              contain symbolic links.  The return status is 0 unless an  error
              occurs  while  reading  the  name of the current directory or an
              invalid option is supplied.

ฉันไม่แน่ใจว่าจะเข้าใจ
ว่าความ

/bin/pwdละเว้น symlink โดยค่าเริ่มต้นอ่านส่วนหนึ่งinfo pwdในคำตอบของฉัน: พิมพ์ชื่อที่ได้รับการแก้ไขอย่างสมบูรณ์สำหรับไดเรกทอรีปัจจุบัน นั่นคือส่วนประกอบทั้งหมดของชื่อที่พิมพ์จะเป็นชื่อไดเรกทอรีจริง - ไม่มีจะเป็นลิงก์สัญลักษณ์
cuonglm

@ user3581976: ดูการปรับปรุงของฉันให้ชัดเจนยิ่งขึ้น
cuonglm

ทำไมถึงมีคำสั่ง -L สำหรับ pwd ถึงแม้ว่ามันจะถูกตั้งค่าตามค่าเริ่มต้น และเชลล์ไม่ใช้คำสั่ง / bin / pwd เพื่อเรียกใช้ pwd?
user3581976

2
@ user3581976: ภาพที่คุณเริ่มเชลล์ด้วยset -o physicalตอนนี้pwdใช้-Pตัวเลือกโดยปริยายถ้าคุณไม่มี-Lตัวเลือกคุณจะพิมพ์เส้นทางที่มี symlink ได้อย่างไร อ่านสิ่งนี้https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.htmlเพื่อทราบว่าset -o physicalทำอะไร
cuonglm

7

เป็นไปได้ที่กระบวนการซักถามระบบไฟล์เพื่อกำหนดไดเรกทอรีการทำงานปัจจุบันโดยใช้วิธีที่ซับซ้อนเกินกว่าจะเป็นหัวข้อเพื่อตอบคำถามนี้ นี่คือสิ่งที่pwdโปรแกรมและgetcwdฟังก์ชั่นห้องสมุดทำ ในยุคแรก ๆ ของ Unix พวกเขาเป็นวิธีเดียวที่จะค้นหาว่าไดเรกทอรีการทำงานของคุณคืออะไร นี่คือส่วนหนึ่งของคำตอบสำหรับคำถามของคุณที่ฉันไม่สามารถหาได้จากคำตอบอื่น ๆ หรือแม้แต่ที่อื่นบนไซต์นี้ (หลังจากการค้นหา 42 วินาที):

  • เมื่อเชลล์เริ่มทำงานเชลล์จะได้รับไดเร็กทอรีการทำงานปัจจุบัน (อาจเป็นการเรียกgetcwd)
  • หลังจากนั้นทุกครั้งที่คุณทำ a cd, pushdหรือpopd, เชลล์จะติดตามไดเร็กทอรีทำงานโดยใช้ฟังก์ชันการจัดการสตริง ตัวอย่างเช่น,

    • หากไดเร็กทอรีการทำงานของคุณคือ/home/simและคุณพิมพ์cd ..เชลล์จะคำนวณว่าไดเร็กทอรีการทำงานของคุณคือ/homeอะไร
    • หากไดเร็กทอรีการทำงานของคุณคือ/home/simและคุณพิมพ์cd .เชลล์จะคำนวณว่าไดเร็กทอรีการทำงานของคุณยังคง/home/simอยู่
    • หากไดเร็กทอรีการทำงานของคุณคือ/home/simและคุณพิมพ์cd aaเชลล์จะคำนวณว่าไดเร็กทอรีการทำงานของคุณคือ/home/sim/aa- โดยไม่ตรวจสอบเพื่อดูว่าaaเป็นลิงก์สัญลักษณ์หรือไม่

    มันไม่นี้เพื่อบันทึก“ค่าใช้จ่าย” getcwdของการโทร แต่นี่เป็นการแลกเปลี่ยนเนื่องจากอาจส่งผลให้ข้อมูลไม่ถูกต้อง

  • pwd(ในตัว) คำสั่งเพียงแค่แสดงเปลือกจำ / คำนวณความคิดของสิ่งที่ไดเรกทอรีการทำงานคือ
  • นอกจากนี้เชลล์ยังใช้แนวคิดที่จำ / คำนวณในสิ่งที่ไดเรกทอรีการทำงานอยู่ในตัวแปรสภาพแวดล้อม PWD เพื่อความสะดวกของกระบวนการผู้ใช้ กระบวนการไม่ควรเชื่อถือได้หากต้องการข้อมูลที่ถูกต้อง

ดังนั้นสิ่งที่สำคัญที่สุดคือเปลือกสามารถสับสนได้ว่ามันอยู่ตรงไหน แต่ถ้าคุณพิมพ์/bin/pwdสิ่งนั้นจะทำงานในกระบวนการที่แยกต่างหากซึ่งไม่สามารถเข้าถึงความคิดของเชลล์เกี่ยวกับไดเร็กตอรี่ที่ใช้งานอยู่และดังนั้นมันจึงเป็นตัวกำหนดไดเร็คทอรี่สำหรับการทำงานที่แท้จริง (ข้อยกเว้น: /bin/pwdโปรแกรมสามารถดูตัวแปรสภาพแวดล้อม PWD และเห็นได้ชัดว่ามันทำเมื่อคุณระบุ-L) นี่เป็นอีกตัวอย่างของวิธีที่เชลล์สามารถสับสน:

cd /home/sim/aa # สมมติว่า/home, /home/simและ/home/sim/aa
# เป็นไดเรกทอรีจริงทั้งหมด (ไม่ใช่ลิงก์สัญลักษณ์)
pwd # ผลลัพธ์: /home/sim/aaซึ่งถูกต้อง
mv ../aa ../bb
pwd # ผลลัพธ์: /home/sim/aaซึ่งไม่ถูกต้อง
/bin/pwd # ผลลัพธ์: /home/sim/bbซึ่งถูกต้อง


และเพียงในกรณีที่คุณไม่ชัดเจนเกี่ยวกับเรื่องนี้ถ้าคุณพิมพ์ln -s . aaและcd aaแล้วไดเรกทอรีการทำงานปัจจุบันของคุณไม่ได้เปลี่ยนแปลงใด ๆ มากกว่ามันไม่เมื่อคุณพิมพ์cd .- cd aaเพราะที่เป็นหลักสิ่งที่คุณทำเมื่อคุณพิมพ์


ขอขอบคุณคำตอบที่ดีมากนี่คือสิ่งที่ฉันรอคอย)
user3581976

2
คำตอบนี้ดูเหมือนเล็กน้อยงอ มีมากไป-Lกว่าการประหยัดค่าใช้จ่าย - และ$PWDเป็นตัวแปรสภาพแวดล้อมที่ผู้ใช้กำหนด POSIX ระบุ - การใช้งานผู้ใช้พื้นที่อาจจะไว้วางใจได้ (? สิ่งที่หมายถึง ... ) อย่างไรก็ตามในขณะที่ฉันไม่ได้เป็นแฟนของ symlink มันเป็นสิทธิพิเศษของผู้ใช้ไปทางอ้อมในทิศทางที่บ้าคลั่งมากที่สุดเท่าที่เขาหรือเธอควรเลือกกับพวกเขา - และนั่นคือสิ่งที่-Lเป็นอะไรมากกว่าอะไร
mikeserv

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