Почему отображается что-то для $ PS3, даже если $ PS3 пусто?

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

Как вы можете видеть, $PS1, $PS2и $PS4имеют значение и работать , как задумано. $PS3пусто (или содержит пробел, табуляцию и т. д.), но selectиспользует #?для $PS3, но когда переменная установлена, она работает нормально.

Почему это ведет себя так и почему это было разработано таким образом?

Motte001
источник

Ответы:

15

Потому что док говорит так:

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

PS3

Значение этой переменной используется в качестве подсказки для команды выбора. Если эта переменная не задана, команда выбора запрашивает '#? '

Джефф Шаллер
источник
2
Ключ здесь является If this variable is not setчастью. Пользователь может попытаться установить его в качестве пустого символа или пробела, или, может быть, даже нулевого
Сергей Колодяжный
11

Похоже, это жестко закодировано в Bash. В execute_cmd.cфункции execute_select_command()есть вот что:

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

Обратите внимание, что это происходит только если PS3не установлено. Если вы установите пустую строку, selectвам с радостью предложат, ну, ничего.

ilkkachu
источник
Можете ли вы предоставить информацию, почему это так?
Motte001
Я могу только догадываться, что это так, что пустой запрос не происходит случайно (поскольку это может сбить с толку). Но я не могу знать наверняка, и это предположение не говорит, почему bash делает это, делая неустановленное значение особым случаем, а не просто устанавливая переменную по умолчанию.
ilkkachu
4

In bash, PS3было установлено, "#? "когда не установлено , что по умолчанию.

Кроме того, ни POSIX , ни его selectне PS3определены, поэтому поведение может быть различным:

  • ksh, mksh, yash, zshИ Шили shустанавливается по умолчанию в "#? ".
  • dash, shсемейная реликвия , busybox shне установленPS3
cuonglm
источник
Yash 2.39 не имеет установленной PS3
Motte001
@ Motte001 Это происходит с моим 2.9
cuonglm
Я проверил это на Ubuntu 16.04
Motte001
1

Другие ответили почему, но вот как - установите PS3 на ноль:

$ 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=выполняет то же самое
Чепнер
@chepner Почему это происходит? Это не устанавливает это "\0", это устанавливает это "".
EKons
Потому что bash написан на C, а внутренне каждая строка в C хранится с завершающим символом NULL. Где-то есть вопрос о U & L с ответом Жиля
Сергей Колодяжный