PS1 = '$ (pwd)' tại sao điều này hoạt động và tại sao điều này khác với PS1 = $ (pwd)


18

Tại sao khi tôi nhập lệnh này, dấu nhắc thay đổi vào thư mục của tôi?

PS1='$(pwd)'

Tôi đang sử dụng các trích dẫn đơn, có nghĩa là không có nội suy, hay còn gọi là Tập echo '$(pwd)'$(pwd)

Hơn nữa, nói rằng chúng tôi đã làm rõ lý do tại sao điều này hoạt động ... tại sao nó hoạt động khác với PS1=$(pwd)? (không có trích dẫn nào cả)

Bằng cách khác, tôi có nghĩa là nếu tôi sử dụng dấu ngoặc kép thì lời nhắc sẽ tiếp tục thay đổi thư mục hiện tại của tôi khi tôi điều hướng qua thiết bị đầu cuối. Nhưng nếu tôi không sử dụng dấu ngoặc kép, thì dấu nhắc sẽ luôn là thư mục mà tôi đã ở khi tôi nhập lệnh lần đầu tiênPS1=$(pwd)

tại sao?


2
Lưu một số chu kỳ CPU và sử dụng PS1 tương đương = '$ PWD'
jlliagre

Câu trả lời:


29

Khi bạn chỉ cần gán một giá trị cho một biến, $(...)biểu thức được ước tính trừ khi nó được đặt trong dấu ngoặc đơn (hoặc dấu gạch chéo ngược được thoát). Để hiểu, hãy thử và so sánh hai:

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

Giá trị của Angay lập tức trở thành chuỗi /home/yourusernamevà rõ ràng là nó không nhớ chuỗi này đến từ đâu, nó vẫn giữ nguyên ngay cả khi bạn thay đổi thư mục. Giá trị của B, tuy nhiên, trở thành chuỗi ký tự $(pwd)mà không được giải thích.

Bây giờ, trong giá trị của PS1một cái gì đó đặc biệt xảy ra: bất cứ khi nào dấu nhắc được in, một số cấu trúc đặc biệt được diễn giải, ví dụ: việc thay thế lệnh $(...)được thực hiện chính xác theo cách nó đã xảy ra ở trên khi gán cho Abiến. Rõ ràng nếu bạn PS1chứa chuỗi ký tự của thư mục chính của bạn (như trên với A) thì không có cách nào nó có thể thay đổi. Nhưng nếu nó chứa chuỗi $(pwd)(như trên với B) thì nó được đánh giá bất cứ khi nào lời nhắc được in và do đó thư mục thực tế của bạn được hiển thị.


14

Trong cả bash và zsh, giá trị của PS1không được sử dụng như một dấu nhắc, nó trải qua một số mở rộng. Các quy tắc khác nhau cho hai vỏ, nhưng trong cả hai trường hợp, một trong những bước là để thực hiện “đô la” mở rộng (thay biến, lệnh thay thế, đánh giá số học) với cú pháp tương tự như trong cú pháp vỏ bình thường ( , , hay , , ) .$VARIABLE${VARIABLE}$(COMMAND)`COMMAND`$((EXPRESSION))$[EXPRESSION]

  • Trong bash, mở rộng đô la được bật theo mặc định, nhưng có thể được tắt bằng shopt -u promptvars.
  • Trong zsh, mở rộng đô la bị tắt theo mặc định, nhưng nhiều người (và hầu hết các khung cấu hình bạn sẽ tìm thấy trên web) bật nó lên setopt prompt_subst.

Khi mở rộng đô la trong lời nhắc được bật, PS1='$(pwd)'đặt PS1thành giá trị 6 ký tự $(pwd)và do đó sẽ $(pwd)được thay thế và do đó pwdlệnh sẽ được thực thi, mỗi khi trình bao hiển thị một dấu nhắc mới. Mặt khác, PS1=$(pwd)thiết lập PS1bất cứ thứ gì là thư mục làm việc hiện tại của shell tại thời điểm đó. Nếu bạn đã tắt mở rộng đô la thì PS1='$(pwd)'sẽ khiến dấu nhắc là chuỗi ký tự $(pwd).

Lưu ý rằng có nhiều cách thuận tiện hơn để nhận thư mục làm việc trong lời nhắc:

  • Trong bash, với một dấu gạch chéo ngược như \w, viết tắt thư mục chính của bạn ~và có thể được cắt bớt bằng cách cài đặt PROMPT_DIRTRIM.
  • Trong zsh, với một phần trăm thoát như %/hoặc%~ ( %/giống như $PWD, %~viết tắt các thư mục chính), có thể có một cài đặt cắt xén.
  • Trong một trong hai shell (và bất kỳ shell kiểu Bourne nào khác), $PWDtương đương với $(pwd): bạn không cần phải chạy một quy trình con để có được thư mục làm việc hiện tại.

7

Bởi vì không có dấu ngoặc kép, $ (pwd) được ước tính khi PS1 được đặt. Với dấu ngoặc kép, việc đánh giá $ (pwd) bị hoãn lại cho đến khi lời nhắc được hiển thị.

Không có dấu ngoặc kép, PS1 được đặt thành thư mục hiện tại tại thời điểm PS1 được đặt. Với các trích dẫn đơn, PS1 được đặt thành $ (pwd), có nghĩa là nó sẽ đánh giá và in thư mục hiện tại mỗi khi dấu nhắc được hiển thị.

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.