Sự khác biệt kỳ lạ giữa pwd và / bin / pwd


15

Tôi đã thêm một symlink vào thư mục hiện tại với ln -s . aa. Nếu tôi thực thi cd aavà sau đó tôi thực hiện pwd, phản hồi là /home/sim/aa.

Nhưng nếu tôi thực hiện /bin/pwdnó sẽ in /home/sim(thư mục hiện tại đã không thay đổi).

Sự khác biệt này đến từ đâu?

Câu trả lời:


17

Trong hầu hết các shell bao gồm bash, pwdlà một shellin:

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

Nếu bạn sử dụng /bin/pwd, bạn phải sử dụng -Ltùy chọn để có kết quả tương tự như nội dung pwd:

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

Theo mặc định, /bin/pwdbỏ qua các liên kết tượng trưng và in thư mục thực tế.

Từ 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.

Các BUILTIN pwdbao gồm liên kết tượng trưng theo mặc định, ngoại trừ việc -Plựa chọn được sử dụng, hoặc -o physicalthiết lập dựng sẵn được kích hoạt.

Từ 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.

Tôi không chắc chắn hiểu được sự xuất phát từ những khác biệt đó
user3581976

/bin/pwdBỏ qua symlink theo mặc định, đọc phần info pwdtrong câu trả lời của tôi: In tên được giải quyết đầy đủ cho thư mục hiện tại. Đó là, tất cả các thành phần của tên được in sẽ là tên thư mục thực tế-- không có thành phần nào là liên kết tượng trưng.
cuonglm

@ user3581976: Xem cập nhật của tôi để biết rõ hơn.
cuonglm

Tại sao có lệnh -L cho pwd mặc dù nó được đặt theo mặc định? Và shell không sử dụng lệnh / bin / pwd để chạy pwd?
dùng3581976

2
@ user3581976: Hình ảnh mà bạn bắt đầu trình bao set -o physical, bây giờ pwd-Ptùy chọn sử dụng theo mặc định, nếu bạn không có -Ltùy chọn, làm thế nào để bạn in đường dẫn chứa symlink? Đọc này https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.htmlđể biết những gì set -o physicalkhông.
cuonglm

7

Có thể một quá trình thẩm vấn hệ thống tệp để xác định thư mục làm việc hiện tại của nó, sử dụng một phương pháp hơi phức tạp để có thể trở thành chủ đề như một câu trả lời cho câu hỏi này. Đây là những gì pwdchương trình và getcwdchức năng thư viện làm. Trong những ngày đầu của Unix, họ là cách duy nhất để tìm ra thư mục làm việc của bạn là gì. Đây là một phần câu trả lời cho câu hỏi của bạn mà tôi không thể tìm thấy trong bất kỳ câu trả lời nào khác, hoặc thậm chí ở bất kỳ nơi nào khác trên trang web này (sau 42 giây tìm kiếm):

  • Khi shell khởi động, nó nhận được thư mục làm việc hiện tại của nó (có thể bằng cách gọi getcwd).
  • Sau đó, bất cứ khi nào bạn thực hiện một cd, pushdhoặc popd, shell sẽ theo dõi thư mục làm việc bằng cách sử dụng các hàm thao tác chuỗi. Ví dụ,

    • Nếu thư mục làm việc của bạn là /home/simvà bạn gõ cd .., shell sẽ tính toán thư mục làm việc của bạn /home.
    • Nếu thư mục làm việc của bạn là /home/simvà bạn gõ cd ., shell sẽ tính toán rằng thư mục làm việc của bạn vẫn còn /home/sim.
    • Nếu thư mục làm việc của bạn là /home/simvà bạn gõ cd aa, shell sẽ tính toán thư mục làm việc của bạn /home/sim/aa- mà không kiểm tra xem liệu đó có phải aalà một liên kết tượng trưng hay không.

    Nó thực hiện điều này để tiết kiệm chi phí gọi điện thoại trên mạng getcwd. Nhưng đây là một sự đánh đổi, vì nó có thể dẫn đến thông tin không chính xác.

  • Lệnh pwd(dựng sẵn) chỉ đơn giản hiển thị khái niệm được nhớ / tính toán của shell về thư mục làm việc là gì.
  • Ngoài ra, shell đặt khái niệm được nhớ / tính toán của nó về thư mục làm việc vào biến môi trường PWD, để thuận tiện cho quá trình người dùng. Một quá trình không bao giờ nên dựa vào điều này nếu nó muốn thông tin chính xác.

Vì vậy, điểm mấu chốt là vỏ có thể bị lẫn lộn về vị trí của nó. Nhưng nếu bạn gõ /bin/pwd, nó chạy trong một quy trình riêng biệt không có quyền truy cập vào khái niệm của shell về thư mục làm việc là gì, và do đó, nó xác định chính thư mục làm việc thực sự, theo cách thức cũ. (Ngoại lệ: /bin/pwdchương trình có thể xem xét biến môi trường PWD và rõ ràng là khi bạn chỉ định -L.) Đây là một ví dụ khác về cách trình bao có thể bị nhầm lẫn:

cd /home/sim/aa # Giả sử rằng /home, /home/sim/home/sim/aa
# là tất cả các thư mục thực (không phải liên kết tượng trưng).
pwd # Đầu ra : /home/sim/aa, đúng.
mv ../aa ../bb
pwd # Đầu ra : /home/sim/aa, không chính xác.
/bin/pwd # Đầu ra : /home/sim/bb, đúng.


Và, chỉ trong trường hợp bạn không rõ về điều này, nếu bạn nhập ln -s . aacd aa, thì thư mục làm việc hiện tại của bạn đã không thay đổi , nhiều hơn so với khi bạn nhập cd .- bởi vì, đó thực chất là những gì bạn đang làm khi bạn nhập cd aa.


Cảm ơn, câu trả lời rất hay, đây là điều tôi đang chờ đợi;)
user3581976

2
Câu trả lời này có vẻ hơi cong . Có nhiều thứ -Lhơn là tiết kiệm chi phí - và $PWDlà biến môi trường do người dùng xác định POSIX - các ứng dụng không gian người dùng có thể nên tin tưởng vào nó (bất cứ điều gì có nghĩa là ...?) . Dù sao, trong khi tôi hoàn toàn không phải là một fan hâm mộ của các liên kết tượng trưng, ​​thì đó là đặc quyền của người dùng để gián tiếp theo nhiều hướng điên rồ mà họ nên chọn với họ - và đó là điều -Lquan trọng hơn bất cứ điều gì.
mikeerv 18/03/2015

1
Đây phải là câu trả lời được chấp nhận (các liên kết tượng trưng không phải là điểm của câu hỏi).
Thomas Dickey
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.