Pourquoi quelque chose pour $ PS3 est-il affiché, même lorsque $ PS3 est vide?

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

Comme vous pouvez le voir, $PS1, $PS2et $PS4ont une valeur et le travail comme prévu. $PS3est vide (ou contient un espace, une tabulation, etc.), mais selectutilise #?for $PS3, mais lorsque la variable est définie, cela fonctionne normalement.

Pourquoi cela se comporte-t-il ainsi et pourquoi a-t-il été conçu de cette façon?

Motte001
la source

Réponses:

15

Parce que le doc le dit:

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

PS3

La valeur de cette variable est utilisée comme invite pour la commande de sélection. Si cette variable n'est pas définie, la commande de sélection vous invite avec '#? "

Jeff Schaller
la source
2
La clé ici fait If this variable is not setpartie. L'utilisateur peut essayer de le définir sur un caractère ou un espace vide, ou peut-être même nul
Sergiy Kolodyazhnyy
11

Il semble être codé en dur dans Bash. Dans execute_cmd.c, fonction execute_select_command(), il y a ceci:

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

Notez que cela ne se produit que s'il PS3n'est pas défini. Si vous le définissez sur une chaîne vide, vous selectserez volontiers invité avec, eh bien, rien.

ilkkachu
la source
Pouvez-vous fournir des informations, pourquoi cela est conçu de cette façon?
Motte001
Je peux seulement deviner que c'est pour qu'une invite vide ne se produise pas par accident (car cela pourrait être déroutant). Mais je ne peux pas être sûr, et cette hypothèse ne dit pas pourquoi bash le fait en faisant de la valeur unset un cas spécial, au lieu de simplement définir la variable par défaut.
ilkkachu
4

Dans bash, a PS3été défini sur "#? "lorsqu'il n'est pas défini , ce qui est par défaut.

De plus, ni n'est défini Posix, de sorte que le comportement peut varier:selectPS3

  • ksh, mksh, yash, zshEt schily shparamètre par défaut défini à "#? ".
  • dash, héritage sh, busybox shne définissent pasPS3
cuonglm
la source
Yash 2.39 n'a pas de jeu PS3
Motte001
@ Motte001 Il le fait avec mon 2.9
cuonglm
Je l'ai testé sur Ubuntu 16.04
Motte001
1

D'autres ont répondu pourquoi, mais voici comment - régler votre PS3 sur 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
Sergiy Kolodyazhnyy
la source
1
PS3=accomplit la même chose
chepner
@chepner Pourquoi accomplit-il une telle chose? Il ne le définit pas "\0", il le définit "".
EKons
Parce que bash est écrit en C et en interne chaque chaîne en C stockée avec un caractère NULL de fin. Il y a une question sur U&L quelque part avec une réponse de Gilles
Sergiy Kolodyazhnyy