Set and Shopt - Why Two?


72

sete shoptsono entrambi integrati nella shell che controllano varie opzioni. Spesso dimentico quali opzioni sono impostate da quale comando e quali opzioni imposta / unsets ( set -o/+o, shopt -s/-u). Perché ci sono due comandi diversi che apparentemente fanno la stessa cosa (e hanno argomenti diversi per farlo)? C'è un modo semplice / mnemonico per ricordare quali opzioni vanno con quale comando?


6
Prova a guardare la seconda riga di help sete help shoptper verificare che anche i loro autori pensino di fare la stessa cosa.
l0b0,

2
"Cambia il valore degli attributi della shell" vs "Cambia l'impostazione di ogni opzione della shell".
Kevin,

2
Nella versione 4.1.5 (1) di Bash dice "Imposta o disattiva i valori delle opzioni della shell e dei parametri posizionali". e "Imposta e disattiva le opzioni della shell.", rispettivamente.
l0b0,

Scrivere manpage ti fa capire ciò che non sai e ti fa provare a formulare cose in un modo in cui non sei sbagliato su ciò di cui provi a scrivere.
sjas,

Risposte:


40

Per quanto ne so, le set -oopzioni sono quelle ereditate da altre shell in stile Bourne (principalmente ksh) e le shoptopzioni sono quelle specifiche di bash. Non c'è logica che io conosca.


1
Qualche documentazione che mostra shoptè ereditata?
Felipe Alvarez,

8
Bene, ci sono set -oopzioni come posix/ physical/ interactive-commentsche non sono presenti kshe shoptaltre che si trovano in altre shell anche kshper alcuni come login_shell/ nullglob. Come dici tu, non c'è logica. All'inizio era probabilmente l'idea (che SHELLOPTS sarebbe stata quella standard e BASHOPTS quella specifica bash), ma che si è persa lungo la strada, e ora finisce per essere fastidiosa e un fiasco di progettazione dell'interfaccia utente.
Stéphane Chazelas,

22

La differenza sta nella variabile d'ambiente modificata usata da bash. L'impostazione con il setcomando risulta in $SHELLOPTS. L'impostazione con il shoptcomando risulta in $BASHOPTS.


9
Ugh! Questo è ancora più confuso. Il mio cervello vuole associarsi shopta $ SH ELL OPT S piuttosto che a $ BA SHOPT S.
Bruno Bronosky


8

Facile ma perso nella storia. Il setcomando è stato originariamente utilizzato per modificare l'ambiente della riga di comando delle shell unix originali /bin/sh. Quindi, man mano che varie versioni di Unix si sono evolute e sono state aggiunte nuove versioni di shell, le persone hanno capito che dovevano essere in grado di cambiare più cose (ambientali) per mantenere la compatibilità degli script di shell. A quel tempo Bash ottenuto molto popolare e gli ulteriori sh ell opt era necessaria ioni, introducendo shopt.

Si può effettivamente vedere questi compat tentativi bilità del 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

Ma non nel 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

2
setpoiché un modo per impostare le opzioni non era nelle shell Unix originali, fu introdotto dalla shell Bourne alla fine degli anni '70. set -o namestesso fu aggiunto successivamente dalla shell Korn, specificata ma facoltativa in POSIX, ancora non supportata dalle versioni "moderne" della shell Bourne come quella /bin/shdi Solaris 10.
Stéphane Chazelas,

5

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

Storicamente, il setcomando veniva utilizzato per attivare e disattivare le opzioni. Con l'aumentare del numero di opzioni, è setdiventato più difficile da usare perché le opzioni sono rappresentate da codici a lettera singola. Di conseguenza, Bash fornisce il comando shopt( opzione shell ) per attivare e disattivare le opzioni in base al nome anziché a una lettera. È possibile impostare alcune opzioni solo per lettera. Altri sono disponibili solo sotto il shoptcomando. Ciò rende la ricerca e l'impostazione di un'opzione particolare un'attività confusa.


3

Sembra che le opzioni "set" siano ereditate dai subshells e non lo siano i negozi.


Bella presa. Mi chiedo se questa sia una scelta intenzionale o un effetto collaterale.
Kevin,

2
@ user29778 Almeno sotto bash 4.1.5 (1) le opzioni impostate con setnon vengono ereditate dalle subshells.Both sete shoptle opzioni non vengono ereditate dalle subshell.
Martin

Puoi indicare la documentazione che descrive le caratteristiche di eredità di entrambi sete shopt?
Felipe Alvarez,

9
Entrambe set -oe le shoptopzioni sono ereditate da subshells ( (...), $(...)componenti della pipeline). Il fatto che siano ereditati da altre bashinvocazioni dipende dal fatto SHELLOPTSche BASHOPTSsiano o meno nell'ambiente.
Stéphane Chazelas,

0

setproviene dalla shell bourne (sh) e fa parte dello standard POSIX, shopttuttavia non è ed è specifica dalla 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

$ 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.