Set and Shopt - Por que dois?

72

sete shoptsão ambos os shell shell que controlam várias opções. Costumo esquecer quais opções são definidas por qual comando e qual opção define / desmarca ( set -o/+o, shopt -s/-u). Por que existem dois comandos diferentes que aparentemente fazem a mesma coisa (e têm argumentos diferentes para fazer isso)? Existe alguma maneira fácil / mnemônica de lembrar quais opções combinam com qual comando?

Kevin
fonte
6
Tente olhar para a segunda linha help sete help shoptverificar se os autores pensam que fazem a mesma coisa.
L0b0
2
"Alterar o valor dos atributos do shell" vs "Alterar a configuração de cada opção do shell".
22412 Kevin
2
No lançamento do Bash 4.1.5 (1), diz "Defina ou desative valores de opções de shell e parâmetros posicionais". e "Definir e desmarcar opções de shell", respectivamente.
L0b0
Escrever páginas de manual faz você perceber o que não sabe e faz com que tente formular as coisas de uma maneira que você não está errado sobre o que tenta escrever.
S2

Respostas:

40

Até onde eu sei, as set -oopções são as que são herdadas de outras conchas no estilo Bourne (principalmente ksh), e as shoptopções são as que são específicas para o bash. Não há lógica que eu conheça.

Gilles 'SO- parar de ser mau'
fonte
11
Alguma documentação que mostra shopté herdada?
Felipe Alvarez
8
Bem, existem set -oopções como posix/ physical/ interactive-commentsque não estão incluídas kshe shoptoutras que estão em outras conchas, incluindo kshalgumas como login_shell/ nullglob. Como você diz, não há lógica. Provavelmente foi a idéia no início (que o SHELLOPTS seria o padrão e o BASHOPTS, o específico do bash), mas que se perdeu ao longo do caminho, e agora acaba sendo irritante e um fiasco de design de interface do usuário.
Stéphane Chazelas
22

A diferença está na variável de ambiente alterada usada pelo bash. A configuração com o setcomando resulta em $SHELLOPTS. A configuração com o shoptcomando resulta em $BASHOPTS.

mug896
fonte
9
Ugh! Isso é ainda mais confuso. Meu cérebro quer associar shoptcom US $ SH ELL OPT S em vez de $ BA shopt S.
de Bruno Bronosky
8

Fácil, mas perdido na história. O setcomando foi originalmente usado para modificar o ambiente da linha de comandos dos shells unix originais /bin/sh. Então, à medida que várias versões do Unix evoluíam e novos sabores de shell eram adicionados, as pessoas perceberam que precisavam ser capazes de mudar mais coisas (ambientais) para manter os scripts de shell compatíveis. Naquela época Bash ficou muito popular e os adicionais sh ell opt íons era necessário, introduzindo shopt.

Você pode realmente ver esses compat tentativas lidade no 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

Mas não no 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
fonte
2
setcomo uma maneira de definir opções não estava nos invólucros originais do Unix, foi introduzido pelo shell Bourne no final dos anos 70. set -o nameem si foi adicionado mais tarde pelo shell Korn, especificado, mas opcional no POSIX, ainda não é suportado pelo "modernos" versões do shell Bourne como o /bin/shde Solaris 10.
Stéphane Chazelas
5

No livro "Linux Shell Scripting with Bash", p 63:

Historicamente, o setcomando era usado para ativar e desativar as opções. À medida que o número de opções aumentou, settornou-se mais difícil de usar, porque as opções são representadas por códigos de letra única. Como resultado, o Bash fornece o comando shopt( opção de shell ) para ativar e desativar as opções por nome, em vez de uma letra. Você pode definir certas opções apenas por letra. Outros estão disponíveis apenas sob o shoptcomando Isso torna encontrar e definir uma opção específica uma tarefa confusa.

LoMaPh
fonte
3

Parece que as opções "set" são herdadas por subshells e os shopts não.

user29778
fonte
Boa pegada. Gostaria de saber se esta é uma escolha intencional ou um efeito colateral.
5133 Kevin
2
@ user29778 Pelo menos no bash 4.1.5 (1), as opções definidas com setnão são herdadas pelos subshells.Both sete shoptopções não são herdadas pelos subshells.
7273 Martin
Você pode apontar para a documentação que descreve as características de herança de ambos sete shopt?
Felipe Alvarez
9
As opções set -oe shoptsão herdadas por subshells ( (...), $(...)componentes de pipeline). A herança de outras bashinvocações depende de estar SHELLOPTSou BASHOPTSnão no ambiente.
Stéphane Chazelas
0

setorigina-se do casco de bourne (sh) e faz parte do padrão POSIX; shoptno entanto, não é e é específico do casco de 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
fonte