Set and Shopt – Por que dois?

set e shopt são ambos shell builtins que controlam vários opções. Freqüentemente, esqueço quais opções são definidas por qual comando e quais opções definem / cancelam (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 vão com qual comando?

Comentários

  • Tente olhar a segunda linha de help set e help shopt para verificar se até seus autores pensam que eles fazem a mesma coisa.
  • " Altere o valor dos atributos de shell " vs " Altere a configuração de cada opção de shell ".
  • No Bash 4.1.5 (1) -release, diz " Defina ou cancele a definição de valores de opções de shell e parâmetros posicionais. " e " Definir e cancelar a definição das opções do shell. ", respectivamente.
  • Escrita manpages faz com que você perceba o que você não sabe e faz com que você tente formular coisas de uma maneira que você não esteja errado sobre o que você tenta escrever.

Resposta

Pelo que eu sei, o opções são aquelas herdadas de outros shells de estilo Bourne (principalmente ksh), e as opções shopt são as específicas do bash. Não há lógica que eu conheça.

Comentários

  • Qualquer documentação que mostre shopt é herdado?
  • Bem, existem set -o opções como posix / physical / interactive-comments que não estão em ksh e shopt aqueles que estão em outro shells incluindo ksh para alguns como login_shell / nullglob. Como você diz, há ' s sem lógica. Provavelmente foi a idéia no início (que SHELLOPTS seriam os padrões e BASHOPTS os específicos do bash), mas isso se perdeu no caminho, e agora acaba sendo irritante e um fiasco de design de IU.

Resposta

A diferença está na variável de ambiente alterada usado pelo bash. Definir com o comando set resulta em . Definir com o comando shopt resulta em $BASHOPTS.

Comentários

  • Ugh! Isso é ainda mais confuso. Meu cérebro deseja associar shopt a $ SH ELL OPT S em vez de $ BA SHOPT S .

Resposta

Resposta

Fácil, mas perdido na história. O comando set foi originalmente usado para modificar o ambiente de linha de comando dos shells originais do unix /bin/sh. Então, conforme várias versões do Unix evoluíram e novos sabores de shell foram adicionados, as pessoas perceberam que precisavam ser capazes de mudar mais coisas (do ambiente) para manter o shell script compatível. Naquela época, o Bash se tornou muito popular e o sh ell opt íons foram necessários, introduzindo shopt.

Você pode realmente ver estes compat tentativas de flexibilidade no comando 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 

Mas não no comando 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 

Comentários

  • set como uma forma de definir opções não ' t nos shells originais do Unix, foi introduzido pelo shell Bourne no final dos anos 70. O próprio set -o name foi adicionado posteriormente pelo shell Korn, especificado, mas opcional em POSIX, ainda não suportado por " moderno " versões do shell Bourne, como /bin/sh do Solaris 10.

Resposta

Do livro “Linux Shell Scripting with Bash”, p 63:

Historicamente, o comando set era usado para ativar e desativar opções. Conforme o número de opções cresceu, set se tornou mais difícil de usar porque as opções são representadas por códigos de uma única letra. Como resultado, o Bash fornece o comando shopt ( opção do shell ) para ativar e desativar opções por nome em vez de letra. Você pode definir certas opções apenas por carta. Outros estão disponíveis apenas sob o comando shopt. Isso torna a localização e configuração de uma determinada opção uma tarefa confusa.

Resposta

Parece que as opções “set” são herdadas por subshells e os compradores não.

Comentários

  • Boa pegada. Eu me pergunto se esta é uma escolha intencional ou um efeito colateral.
  • @ user29778 Pelo menos no bash 4.1.5 (1) as opções definidas com set não são herdados por subshells. Ambas as opções set e shopt não são herdadas por subshells.
  • Você pode apontar para a documentação que descreve as características de herança de set e shopt?
  • Ambos set -o e shopt opções são herdadas por subshells ((...), $(...), componentes do pipeline). Se eles são herdados por outras bash invocações depende se SHELLOPTS ou BASHOPTS estão no ambiente ou não.

Resposta

set se origina do bourne shell (sh) e faz parte do padrão POSIX, shopt não é e é específico do 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 $ 

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *