Set and Shopt - Pourquoi deux?

72

setet shoptsont tous deux intégrés au shell qui contrôlent diverses options. J'oublie souvent quelles options sont définies par quelle commande et quelles options sont définies / non définies ( set -o/+o, shopt -s/-u). Pourquoi deux commandes différentes font-elles apparemment la même chose (et ont des arguments différents pour le faire)? Existe-t-il un moyen simple / mnémonique de se rappeler quelles options vont avec quelle commande?

Kevin
la source
6
Essayez de regarder la deuxième ligne de help setet help shoptvérifiez que même leurs auteurs pensent qu'ils font la même chose.
l0b0
2
"Modifier la valeur des attributs du shell" vs "Modifier le réglage de chaque option du shell".
Kevin
2
Dans Bash 4.1.5 (1), il est indiqué dans Libération, "Valeurs définies ou non définies pour les options du shell et les paramètres de position". et "Définir et désactiver les options du shell.", respectivement.
l0b0
En écrivant des pages de manuel, vous réalisez ce que vous ne savez pas et essayez de formuler les choses de manière à ne pas vous tromper.
Sjas

Réponses:

40

Autant que je sache, les set -ooptions sont celles héritées d'autres shells de type Bourne (principalement ksh), et les shoptoptions sont celles spécifiques à bash. Il n'y a pas de logique à ma connaissance.

Gilles, arrête de faire le mal
la source
1
Toute documentation qui montre shoptest héritée?
Felipe Alvarez
8
Eh bien, il existe des set -ooptions telles que posix/ physical/ interactive-commentsqui ne figurent pas dans ksh, et shoptcelles qui se trouvent dans d’autres shell, y compris kshpour certains comme login_shell/ nullglob. Comme tu le dis, il n'y a pas de logique. C'était probablement l'idée de départ (que SHELLOPTS soient les standards, et BASHOPTS les spécifiques), mais cela s'est perdu en cours de route, et cela finit par être ennuyeux et un fiasco de conception d'interface utilisateur.
Stéphane Chazelas
22

La différence réside dans la variable d'environnement modifiée utilisée par bash. Définir avec la setcommande résulte en $SHELLOPTS. Définir avec la shoptcommande résulte en $BASHOPTS.

mug896
la source
9
Pouah! C'est encore plus déroutant. Mon cerveau veut s'associer shoptavec $ SH ELL OPT S plutôt que $ BA SHOPT S.
Bruno Bronosky
8

Facile mais perdu dans l'histoire. La setcommande a été utilisée à l'origine pour modifier l'environnement de ligne de commande des shells Unix d'origine /bin/sh. Puis, à mesure que différentes versions d'Unix ont évolué et que de nouvelles versions de shell ont été ajoutées, les utilisateurs ont compris qu'ils devaient pouvoir changer davantage de choses (d'environnement) afin de conserver la compatibilité des scripts de shell. A cette époque Bash est devenu très populaire et les autres sh ELL opt ions était nécessaire, l' introduction shopt.

Vous pouvez voir ces compat tentatives de de la bilité shoptcommande.

$ shopt
autocd          off
cdable_vars     off
cdspell         off
checkhash       off
checkjobs       off
checkwinsize    off
cmdhist         on
compat31        off
compat32        off
compat40        off
compat41        off
compat42        off
complete_fullquote      on
direxpand       off
dirspell        off
dotglob         off
execfail        off
expand_aliases  on
extdebug        off
extglob         off
extquote        on
failglob        off
force_fignore   on
globstar        off
globasciiranges off
gnu_errfmt      off
histappend      on
histreedit      off
histverify      off
hostcomplete    on
huponexit       off
interactive_comments    on
lastpipe        off
lithist         off
login_shell     on
mailwarn        off
no_empty_cmd_completion off
nocaseglob      on
nocasematch     off
nullglob        off
progcomp        on
promptvars      on
restricted_shell        off
shift_verbose   off
sourcepath      on
xpg_echo        off

Mais pas dans la setcommande.

$ set -o
allexport       off
braceexpand     on
emacs           on
errexit         off
errtrace        off
functrace       off
hashall         on
histexpand      on
history         on
igncr           off
ignoreeof       off
interactive-comments    on
keyword         off
monitor         on
noclobber       off
noexec          off
noglob          off
nolog           off
notify          off
nounset         off
onecmd          off
physical        off
pipefail        off
posix           off
privileged      off
verbose         off
vi              off
xtrace          off
emigenix
la source
2
setcomme moyen de définir les options ne figurait pas dans les shells Unix d’origine, il a été introduit par le shell Bourne à la fin des années 70. set -o namelui-même a été ajouté plus tard par le shell Korn, spécifié mais facultatif dans POSIX, mais pas encore pris en charge par les versions "modernes" du shell Bourne comme celui /bin/shde Solaris 10.
Stéphane Chazelas
5

Extrait du livre "Linux Shell Scripting with Bash", p 63:

Historiquement, la setcommande était utilisée pour activer et désactiver les options. À mesure que le nombre d'options augmentait, il setdevenait de plus en plus difficile à utiliser car les options étaient représentées par des codes à une lettre. En conséquence, Bash fournit la commande shopt( option du shell ) permettant d'activer et de désactiver les options par leur nom plutôt que par une lettre. Vous pouvez définir certaines options uniquement par lettre. D'autres ne sont disponibles que sous la shoptcommande. Cela rend la recherche et la définition d'une option particulière une tâche confuse.

LoMaPh
la source
3

Il semble que les options "set" soient héritées par les sous-shell et que les options ne le soient pas.

utilisateur29778
la source
Belle prise. Je me demande s’il s’agit d’un choix intentionnel ou d’un effet secondaire.
Kevin
2
@ user29778 Au moins sous bash 4.1.5 (1), les options définies avec setne sont pas héritées par les sous set- shell . Les shoptoptions et les options ne sont pas héritées par les sous-shell.
Martin
Pouvez-vous pointer sur la documentation qui décrit les caractéristiques d'héritage de setet shopt?
Felipe Alvarez
9
Les deux options set -oet shoptsont héritées par les sous-shell ( (...), $(...)composants de pipeline). Qu'elles soient héritées par d'autres bashinvocations SHELLOPTSou non, elles BASHOPTSdépendent de l'environnement.
Stéphane Chazelas
0

setprovient de la bourne shell (sh) et fait partie du standard POSIX, shoptmais n'est pas et est spécifique à la bourne-again shell (bash):

0 sjas@ssg 14:31:45 ~  
set | grep -e SHELLOPTS -e BASHOPTS
BASHOPTS=checkwinsize:cmdhist:complete_fullquote:dotglob:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:progcomp:promptvars:sourcepath
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor

0 sjas@ssg 14:31:51 ~  
shopt | column -t | grep -v off
checkwinsize             on
cmdhist                  on
complete_fullquote       on
dotglob                  on
expand_aliases           on
extglob                  on
extquote                 on
force_fignore            on
histappend               on
interactive_comments     on
progcomp                 on
promptvars               on
sourcepath               on

0 sjas@ssg 14:31:57 ~  
set -o | column -t | grep -v off
braceexpand           on
emacs                 on
hashall               on
histexpand            on
history               on
interactive-comments  on
monitor               on

0 sjas@ssg 14:37:41 ~ 
sh 

$ set -o
Current option settings
errexit         off
noglob          off
ignoreeof       off
interactive     on
monitor         on
noexec          off
stdin           on
xtrace          off
verbose         off
vi              off
emacs           off
noclobber       off
allexport       off
notify          off
nounset         off
priv            off
nolog           off
debug           off

$ shopt
sh: 3: shopt: not found

$ 
sjas
la source