Set and Shopt - Warum zwei?

72

setund shoptsind beide Shell-Builtins, die verschiedene Optionen steuern. Ich vergesse oft, welche Optionen von welchem ​​Befehl gesetzt werden und welche Option setzt / deaktiviert ( set -o/+o, shopt -s/-u). Warum gibt es zwei verschiedene Befehle, die anscheinend dasselbe tun (und unterschiedliche Argumente dafür haben)? Gibt es eine einfache Möglichkeit, sich zu merken, welche Optionen zu welchem ​​Befehl gehören?

Kevin
quelle
6
Schauen Sie sich die zweite Zeile von an help setund stellen Sie help shoptsicher, dass auch die Autoren der Ansicht sind, dass sie dasselbe tun.
10.
2
"Ändern Sie den Wert der Shell-Attribute" vs "Ändern Sie die Einstellung jeder Shell-Option".
Kevin
2
In Bash 4.1.5 (1) -Release steht "Werte von Shell-Optionen und Positionsparametern setzen oder entfernen". und "Shell-Optionen festlegen und deaktivieren".
10.
Durch das Schreiben von Manpages wird Ihnen klar, was Sie nicht wissen, und Sie können versuchen, Dinge so zu formulieren, dass Sie nicht falsch sind, worüber Sie zu schreiben versuchen.
Sjas

Antworten:

40

Soweit ich weiß, sind die set -oOptionen diejenigen, die von anderen Bourne-artigen Shells (meistens ksh) geerbt wurden, und die shoptOptionen sind diejenigen, die spezifisch für bash sind. Ich kenne keine Logik.

Gilles
quelle
1
Irgendeine Dokumentation, die zeigt, shoptwird geerbt?
Felipe Alvarez
8
Nun, es gibt set -oOptionen wie posix/ physical/ interactive-comments, die nicht in ksh, und shoptdiejenigen , die in anderen Shells sind darunter kshfür einige wie login_shell/ nullglob. Wie Sie sagen, es gibt keine Logik. Es war wahrscheinlich die Idee am Anfang (dass SHELLOPTS die Standardidee sein würde und BASHOPTS die bashspezifischen), aber das ging auf dem Weg verloren und jetzt ist es nur noch ärgerlich und ein Fiasko beim Design der Benutzeroberfläche.
Stéphane Chazelas
22

Der Unterschied liegt in der geänderten Umgebungsvariablen, die von bash verwendet wird. Die Einstellung mit dem setBefehl führt zu $SHELLOPTS. Die Einstellung mit dem shoptBefehl führt zu $BASHOPTS.

mug896
quelle
9
Pfui! Das ist noch verwirrender. Mein Gehirn möchte lieber shoptmit $ SH ELL OPT S als mit $ BA SHOPT S in Verbindung treten .
Bruno Bronosky
8

Einfach, aber verloren in der Geschichte. Der setBefehl wurde ursprünglich verwendet, um die Befehlszeilenumgebung der ursprünglichen Unix-Shells zu ändern /bin/sh. Als sich dann verschiedene Unix-Versionen entwickelten und neue Shell-Varianten hinzukamen, wurde den Leuten klar, dass sie in der Lage sein mussten, mehr (Umgebungs-) Dinge zu ändern, um die Kompatibilität mit Shell-Skripten zu gewährleisten. Damals bekam Bash sehr beliebt und die zusätzlichen sh ell opt - Ionen benötigt wurde, die Einführung shopt.

Sie können diese Kompatibilitätsversuche tatsächlich im shoptBefehl sehen.

$ 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

Aber nicht im setBefehl.

$ 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
quelle
2
setDa Optionen nicht in den ursprünglichen Unix-Shells festgelegt werden konnten, wurde sie Ende der 70er Jahre von der Bourne-Shell eingeführt. set -o nameselbst wurde später von der Korn-Shell hinzugefügt, die in POSIX angegeben, aber optional ist, und von "modernen" Versionen der Bourne-Shell wie der /bin/shvon Solaris 10 noch nicht unterstützt wird .
Stéphane Chazelas
5

Aus dem Buch "Linux Shell Scripting mit Bash", S. 63:

In der Vergangenheit wurde der setBefehl zum Ein- und Ausschalten von Optionen verwendet. Mit setzunehmender Anzahl von Optionen wurde die Verwendung schwieriger, da Optionen durch einzelne Buchstabencodes dargestellt werden. Infolgedessen stellt Bash den Befehl shopt( Shell-Option ) bereit, mit dem Optionen nach Namen anstelle eines Buchstabens ein- und ausgeschaltet werden können. Sie können bestimmte Optionen nur durch Buchstaben festlegen. Andere sind nur unter dem shoptBefehl verfügbar . Dies macht das Finden und Einstellen einer bestimmten Option zu einer verwirrenden Aufgabe.

LoMaPh
quelle
3

Es sieht so aus, als ob "Set" -Optionen von Subshells geerbt werden und Shopts nicht.

user29778
quelle
Schöner Fang. Ich frage mich, ob dies eine absichtliche Entscheidung oder ein Nebeneffekt ist.
Kevin
2
@ user29778 Zumindest unter Bash 4.1.5 (1) werden die mit setgesetzten Optionen nicht von Subshells geerbt. Beide setund shoptOptionen werden nicht von Subshells geerbt.
Martin
Können Sie auf die Dokumentation verweisen, die die Vererbungseigenschaften von setund beschreibt shopt?
Felipe Alvarez
9
Sowohl set -ound shoptOptionen werden von Subshells vererbt ( (...), $(...), Pipeline - Komponenten). Ob sie von anderen übernommen werden bashAnrufungen hängt davon ab , ob SHELLOPTSoder BASHOPTSsind in der Umwelt oder nicht.
Stéphane Chazelas
0

setstammt aus der bourne-Shell (sh) und ist Teil des POSIX-Standards, shoptist jedoch nicht und bourne-again-Shell (bash) -spezifisch:

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
quelle