Tại sao một cái gì đó cho $ PS3 được hiển thị, ngay cả khi $ PS3 trống?


9
$ echo $PS1
$
$ echo $PS2
>
$ echo $PS3

$ echo $PS4
+
$ select i in 1 2 3
> do
> case $i in
> 1)
> echo 1
> ;;
> *)
> ;;
> esac
> done
1) 1
2) 2
3) 3
#? 1
1
$ PS3="##? "
$ select i in 1 2 3; do case $i in 1) echo 1; ;; *) ;; esac; done
1) 1
2) 2
3) 3
##? 1
1

Như bạn có thể thấy, $PS1, $PS2$PS4có một giá trị và làm việc như dự định. $PS3trống (hoặc chứa một khoảng trắng, tab, v.v.), nhưng selectđang sử dụng #?cho $PS3, nhưng khi biến được đặt, nó hoạt động bình thường.

Tại sao điều này hành xử theo cách này và tại sao nó được thiết kế theo cách này?

Câu trả lời:


15

Bởi vì tài liệu nói như vậy:

https://www.gnu.org/software/bash/manual/html_node/Bash-Variabled.html#Bash-Variabled

PS3

Giá trị của biến này được sử dụng làm lời nhắc cho lệnh select. Nếu biến này không được đặt, lệnh select sẽ nhắc với '#? '


2
Chìa khóa ở đây là If this variable is not setmột phần. Người dùng có thể thử đặt nó thành ký tự trống hoặc dấu cách hoặc thậm chí là null
Sergiy Kolodyazhnyy

11

Nó dường như được mã hóa cứng trong Bash. Trong execute_cmd.cchức năng execute_select_command(), có cái này:

ps3_prompt = get_string_value ("PS3");
if (ps3_prompt == 0)
    ps3_prompt = "#? ";

Lưu ý rằng nó chỉ xảy ra nếu PS3không được đặt. Nếu bạn đặt nó thành một chuỗi trống, selectvui vẻ sẽ nhắc bạn với, tốt, không có gì.


Bạn có thể cung cấp thông tin, tại sao điều này được thiết kế theo cách này?
Motte001

Tôi chỉ có thể đoán rằng đó là một dấu nhắc trống không xảy ra do tai nạn (vì điều đó có thể gây nhầm lẫn). Nhưng tôi không thể biết chắc chắn, và giả định đó không cho biết tại sao bash làm điều đó bằng cách biến giá trị unset thành trường hợp đặc biệt, thay vì chỉ đặt biến theo mặc định.
ilkkachu

4

Trong bash, PS3được đặt thành "#? "khi không được đặt , đó là mặc định.

Ngoài ra, POSIX selectcũng không PS3được xác định, vì vậy hành vi có thể thay đổi:

  • ksh, mksh, yash, zshVà Schily shthiết lập mặc định để "#? ".
  • dash, gia truyền sh, busybox shkhông được đặtPS3

Yash 2.39 không có bộ PS3
Motte001

@ Motte001 Nó hoạt động với 2.9
cuonglm

Tôi đã thử nghiệm nó trên Ubuntu 16.04
Motte001

1

Những người khác đã trả lời tại sao, nhưng đây là cách - đặt PS3 của bạn thành null:

$ PS3=$'\0'
$ select i in 1 2 3; do case $i in 1) echo "option #" 1; ;; *) ;; esac; done
1) 1
2) 2
3) 3
1
option # 1

1
PS3=hoàn thành điều tương tự
chepner

@chepner Tại sao nó hoàn thành một việc như vậy? Nó không đặt nó thành "\0", nó đặt nó thành "".
EKons

Bởi vì bash được viết bằng C và bên trong mỗi chuỗi trong C được lưu với ký tự NULL kết thúc. Có một câu hỏi về U & L ở đâu đó với câu trả lời của Gilles
Sergiy Kolodyazhnyy
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.