set
et shopt
sont les deux coquillées qui contrôlent diverses options. J'oublie souvent quelles options sont définies par quelle commande et quelle option définit/désentrée (set -o/+o
, shopt -s/-u
). Pourquoi y a-t-il deux commandes différentes qui semblent faire la même chose (et avoir des arguments différents à le faire)? Y a-t-il un moyen facile/mnémonique de rappeler quelles options vont avec quelle commande?
Pour autant que je sache, le set -o
Les options sont celles qui sont héritées des autres coquilles de style Bourne (surtout ksh) et les options shopt
sont celles qui sont spécifiques à Bash. Il n'y a pas de logique que je connaisse.
La différence est dans la variable d'environnement modifiée utilisée par Bash. Réglage avec la commande set
donne les résultats $SHELLOPTS
. Réglage avec la commande shopt
donne les résultats $BASHOPTS
.
set
est POSIX 7: options définies ou non définitionnelles et paramètres de positionnement | PUBS.OPENGROUP.ORG
shopt
n'est pas: Shell & Utilities: TOC détaillé | pubs.opengroup.org
Probablement liée à l'histoire mentionnée par @gilles.
Facile mais perdu dans l'histoire. La commande set
a été utilisée à l'origine pour modifier l'environnement de la ligne de commande des coquilles UNIX d'origine /bin/sh
. Ensuite, différentes versions UNIX ont évolué et que de nouvelles saveurs de coquilles ont été ajoutées, les personnes ont réalisé qu'ils devaient pouvoir modifier plus de choses (environnement) afin de maintenir les scripts de shell compatibles. A cette époque, Bash a été très populaire et le supplément SH ell opt ions était nécessaire, introduisant shopt
.
Vous pouvez réellement voir ces tentatives d'injection compat dans la commande shopt
.
$ 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 commande set
.
$ 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
Du livre "Script Shell Linux avec Bash", P 63:
Historiquement, la commande
set
a été utilisée pour activer et désactiver les options. Comme le nombre d'options augmentait,set
est devenu plus difficile à utiliser car les options sont représentées par des codes de lettres uniques. En conséquence, BASH fournit la commandeshopt
(option shell) pour activer et désactiver les options par nom au lieu d'une lettre. Vous pouvez définir certaines options uniquement par lettre. D'autres sont disponibles uniquement sous la commandeshopt
. Cela facilite la recherche et la définition d'une option particulière une tâche déroutante.
On dirait que des options "Set" sont héritées par des sous-articulations et des magasins ne le sont pas.
set
provient de la coque de Bourne (SH) et fait partie de la norme POSIX, shopt
est cependant non et n'est pas spécifique à Bourne (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
$