Set and Shopt: ¿por qué dos?

72

sety shoptson ambos componentes integrados de shell que controlan varias opciones. A menudo se olvide qué opciones son fijados por el que mando, y que establece opción / desarma ( set -o/+o, shopt -s/-u). ¿Por qué hay dos comandos diferentes que aparentemente hacen lo mismo (y tienen diferentes argumentos para hacerlo)? ¿Hay alguna manera fácil / mnemónica de recordar qué opciones van con cada comando?

Kevin
fuente
66
Intenta mirar la segunda línea help sety help shoptverificar que incluso sus autores piensan que hacen lo mismo.
l0b0
2
"Cambiar el valor de los atributos de shell" frente a "Cambiar la configuración de cada opción de shell".
Kevin
2
En Bash 4.1.5 (1) -release dice "Establecer o desarmar valores de opciones de shell y parámetros posicionales". y "Establecer y desarmar opciones de shell", respectivamente.
l0b0
Escribir páginas de manual te hace darte cuenta de lo que no sabes y te hace intentar formular cosas de una manera que no te equivoques sobre lo que intentas escribir.
sjas

Respuestas:

40

Hasta donde sé, las set -oopciones son las que se heredan de otros shells de estilo Bourne (principalmente ksh), y las shoptopciones son las específicas de bash. No hay lógica que yo sepa.

Gilles 'SO- deja de ser malvado'
fuente
1
¿Alguna documentación que muestra shoptes heredada?
Felipe Alvarez
8
Bueno, hay set -oopciones como posix/ physical/ interactive-commentsque no están incluidas kshy shoptotras que están en otros shells, incluidas kshalgunas como login_shell/ nullglob. Como dices, no hay lógica. Probablemente fue la idea al principio (que SHELLOPTS serían los estándar y BASHOPTS los específicos de bash), pero eso se perdió en el camino, y ahora termina siendo molesto y un fiasco de diseño de interfaz de usuario.
Stéphane Chazelas
22

La diferencia está en la variable de entorno modificada utilizada por bash. La configuración con el setcomando da como resultado $SHELLOPTS. La configuración con el shoptcomando da como resultado $BASHOPTS.

mug896
fuente
9
Ugh! Eso es aún más confuso. Mi cerebro quiere asociarse shoptcon $ SH ELL OPT S en lugar de $ BA SHOPT S.
Bruno Bronosky
8

Fácil pero perdido en la historia. El setcomando se usó originalmente para modificar el entorno de línea de comando de los shells originales de Unix /bin/sh. Luego, a medida que evolucionaron varias versiones de Unix, y se agregaron nuevos sabores de shell, las personas se dieron cuenta de que necesitaban poder cambiar más cosas (del entorno) para mantener la compatibilidad de los scripts de shell. En ese momento del golpe se puso muy popular y los adicionales sh ell opt se necesitaba iones, la introducción shopt.

En realidad se puede ver estas compat intentos bilidad en el shoptcomando.

$ 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

Pero no en el setcomando.

$ 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
fuente
2
setcomo una forma de establecer opciones no estaba en los shells originales de Unix, fue introducido por el shell Bourne a finales de los 70. set -o namesí mismo fue agregado más tarde por el shell Korn, especificado pero opcional en POSIX, aún no soportado por versiones "modernas" del shell Bourne como el /bin/shde Solaris 10.
Stéphane Chazelas
5

Del libro "Linux Shell Scripting with Bash", p 63:

Históricamente, el setcomando se usaba para activar y desactivar las opciones. A medida que crecía el número de opciones, se sethizo más difícil de usar porque las opciones están representadas por códigos de una letra. Como resultado, Bash proporciona el comando shopt( opción de shell ) para activar y desactivar las opciones por nombre en lugar de una letra. Puede establecer ciertas opciones solo por letra. Otros están disponibles solo bajo el shoptcomando. Esto hace que encontrar y configurar una opción particular sea una tarea confusa.

LoMaPh
fuente
3

Parece que las opciones de "conjunto" son heredadas por las subcapas y los shopts no.

usuario29778
fuente
Buena atrapada. Me pregunto si esta es una elección intencional o un efecto secundario.
Kevin
2
@ user29778 Al menos bajo golpe 4.1.5 (1) las opciones establecidas con setno son heredados por subshells.Both sety shoptopciones no se heredan por subcapas.
Martin
¿Puede señalar la documentación que describe las características de herencia de ambos sety shopt?
Felipe Alvarez
9
Tanto set -oy shoptopciones son heredados por subniveles ( (...), $(...), componentes de canalización). Ya sea que son heredados por otras bashinvocaciones depende de si SHELLOPTSo BASHOPTSse encuentran en el medio ambiente o no.
Stéphane Chazelas
0

setse origina en el shell bourne (sh) y es parte del estándar POSIX; shoptsin embargo, no es y es específico del shell bourne-again (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
fuente