Cú pháp hợp lệ của $ $ PS1-} có phải là cú pháp hợp lệ không và nó khác với cú pháp đơn giản $ PS1 USD như thế nào?


12

Tôi đang xem một kịch bản có:

if [ "${PS1-}" ]; then

Điều đó -gây khó khăn cho tôi một chút bởi vì nó dường như không theo cú pháp chuẩn của Posix hoặc Bash. Đây là một số cú pháp phức tạp đã tồn tại mãi mãi, hoặc nó là một lỗi đánh máy? Bất kỳ tài liệu tham khảo nào về tiêu chuẩn / tài liệu sẽ được đánh giá cao.

Thông thường tôi sẽ mã hóa nó:

if [ "$PS1" ]; then

Cái nào đúng hơn hay có sự khác biệt giữa chúng?

Câu trả lời:


12

Đây chắc chắn là cú pháp POSIX . Diễn giải:

Sử dụng ${parameter-word}, nếu parameter

  • đặt và không null, sau đó thay thế giá trị của parameter,
  • đặt nhưng null, sau đó thay thế null và
  • không đặt, sau đó thay thế word.

Phiên ví dụ:

$ echo "${parameter-word}"
word
$ parameter=
$ echo "${parameter-word}"

$ parameter=value
$ echo "${parameter-word}"
value

"Null" ở đây chỉ đơn giản có nghĩa là chuỗi trống. Chẳng có giá trị null đặc biệt nào trong các vỏ POSIX, ngược lại với SQL, chẳng hạn.

Điều này cũng được ghi lại trong phần "Mở rộng tham số" của man bash.


1
Tôi đoán bash và dash man-page là không đầy đủ, vì họ không đề cập đến cú pháp này (lẻ)!
Gregor

1
@Gregor Cả hai hướng dẫn đều đề cập đến điều này. Trong hướng dẫn Bash, nó nằm trong đoạn trước danh sách các mở rộng tham số và trong hướng dẫn Dash, nó nằm trong đoạn sau.
Kusalananda

1
OK, "Bỏ dấu hai chấm ...." Tôi không thấy điều đó :(
Gregor

zshlà lớp vỏ duy nhất mà tôi biết có đề cập đến các biến thể không có dấu hai chấm một cách rõ ràng, thay vì chỉ ghi chú những gì bỏ qua dấu hai chấm.
chepner

1
@pts, văn bản trong POSIX khá nhiều sử dụng thuật ngữ "null", có thể giải thích việc sử dụng nó trong các trang hướng dẫn.
ilkkachu

23

Việc mở rộng biến ${parameter:-word}sẽ sử dụng giá trị $parameternếu nó được đặt và không null (không phải là một chuỗi rỗng), nếu không nó sẽ sử dụng chuỗi word.

Bỏ qua :sẽ không kiểm tra xem giá trị có trống không, chỉ khi nó không được đặt hay không.

Điều này có nghĩa là ${PS1-}sẽ mở rộng thành giá trị $PS1nếu nó được đặt, nhưng thành một chuỗi trống nếu nó trống hoặc không được đặt. Trong trường hợp này, điều này hoàn toàn giống như ${PS1:-}chuỗi sau -cũng trống.

Sự khác biệt giữa "${PS1-}""$PS1"là tinh tế, như @Rakesh Sharma lưu ý: cả hai sẽ mở rộng thành giá trị của $PS1hoặc thành một chuỗi trống nếu nó không được đặt. Ngoại lệ là khi set -uhoạt động, trong trường hợp mở rộng các biến không đặt sẽ gây ra lỗi . Giá trị mặc định (trống) được đặt theo "${PS1-}"chu vi này, mở rộng một unset PS1thành chuỗi trống mà không có lỗi.

Đây là cú pháp tiêu chuẩn ( bắt nguồn từ shell Bourne vào cuối những năm 70 ), cũng như một vài bản mở rộng tương tự khác.


Và vì nó được trích dẫn, nó giống như "$PS1", vì nếu PS1trống, nó trống và các trích dẫn giữ cho từ không biến mất hoàn toàn.
ilkkachu

4
Miễn set -ulà không có hiệu lực. Khi tùy chọn danh từ được bật, thì "$ PS1" => sẽ báo lỗi. "$ {PS-}" sẽ không.

@RakeshSharma đó là một điểm tốt. Cú pháp khác nhau thực sự có thể mang lại kết quả khác nhau tùy thuộc vào tùy chọn danh từ, vì vậy, phép thử ["$ {tham số-}"] có lẽ đúng hơn!
Gregor

1
@Kusalananda: Xin lưu ý rằng ${parameter:-word}sẽ sử dụng giá trị $parameternếu nó là NON-NULL. Trong tất cả các trường hợp khác (có nghĩa là: đặt nhưng NULL hoặc bỏ đặt) nó sẽ sử dụng word. Từ ngữ của bạn:if its set or null

@ikkachu: Vâng, đúng rồi. Chỉ khi các biến là set AND nonnull=> sử dụng chính nó. Ngược lại, ( set but NULL OR unset) => sử dụng từ.

6

Cú pháp:

${parameter:-word}

và một hình thức đặc biệt:

${parameter-word}

cú pháp hợp lệ trong shell POSIX , có nghĩa là sử dụng giá trị mặc định wordnếu parameterkhông được đặt hoặc null.


Thông thường, với wordtrống, sau đó:

${parameter-}

và:

$parameter

hoặc là:

${parameter}

là tương đương.

Nhưng dưới tác dụng của set -u, tất cả các biến unset khiến shell bị chấm dứt. ${parameter-}được sử dụng để bỏ qua quy tắc nghiêm ngặt đó. Nó hoạt động trong cả hai trường hợp nên có, đó là cách chính xác hơn.

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.