Set and Shopt - Why Two?

72

setdan shoptkeduanya builtin shell yang mengontrol berbagai opsi. Saya sering lupa opsi mana yang diatur oleh perintah mana, dan opsi mana yang ditetapkan / tidak disetel ( set -o/+o, shopt -s/-u). Mengapa ada dua perintah berbeda yang tampaknya melakukan hal yang sama (dan memiliki argumen berbeda untuk melakukannya)? Apakah ada cara mudah / mnemonic untuk mengingat opsi mana yang pergi dengan perintah yang mana?

Kevin
sumber
6
Coba lihat baris kedua help setdan help shoptuntuk memverifikasi bahwa bahkan penulis mereka berpikir mereka melakukan hal yang sama.
l0b0
2
"Ubah nilai atribut shell" vs "Ubah pengaturan setiap opsi shell".
Kevin
2
Dalam Bash 4.1.5 (1) -release dikatakan "Set atau unset nilai opsi shell dan parameter posisi." dan "Set dan hapus pilihan shell.", masing-masing.
l0b0
Menulis halaman manual membuat Anda menyadari apa yang tidak Anda ketahui dan membuat Anda mencoba merumuskan hal-hal dengan cara yang salah tentang apa yang Anda coba tulis.
sjas

Jawaban:

40

Sejauh yang saya tahu, set -oopsinya adalah yang diwarisi dari cangkang Bourne-style lainnya (kebanyakan ksh), dan shoptopsinya adalah yang khusus untuk bash. Tidak ada logika yang saya tahu.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
Adakah dokumentasi yang menunjukkan shoptwarisan?
Felipe Alvarez
8
Nah, ada set -oopsi seperti posix/ physical/ interactive-commentsyang tidak ada ksh, dan shoptyang ada di shell lain termasuk kshuntuk beberapa like login_shell/ nullglob. Seperti yang Anda katakan, tidak ada logika. Mungkin itu adalah ide di awal (bahwa SHELLOPTS akan menjadi yang standar, dan BASHOPTS yang spesifik untuk bash), tapi itu hilang di sepanjang jalan, dan sekarang itu berakhir dengan menjengkelkan dan kegagalan desain UI.
Stéphane Chazelas
22

Perbedaannya adalah dalam variabel lingkungan yang diubah yang digunakan oleh bash. Pengaturan dengan setperintah menghasilkan $SHELLOPTS. Pengaturan dengan shoptperintah menghasilkan $BASHOPTS.

mug896
sumber
9
Ugh! Itu bahkan lebih membingungkan. Otak saya ingin bergaul shoptdengan $ SH ELL OPT S daripada $ BA SHOPT S.
Bruno Bronosky
8

Mudah tapi hilang dalam sejarah. The setperintah awalnya digunakan untuk memodifikasi lingkungan baris perintah dari kerang unix asli /bin/sh. Kemudian ketika berbagai versi Unix berkembang, dan citarasa cangkang baru ditambahkan, orang-orang menyadari bahwa mereka perlu dapat mengubah lebih banyak (lingkungan) hal-hal untuk menjaga agar skrip shell kompatibel. Pada saat itu Bash menjadi sangat populer dan tambahan sh ell opt ion diperlukan, memperkenalkan shopt.

Anda benar-benar dapat melihat ini compat upaya ibility di shoptperintah.

$ 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

Tetapi tidak dalam setperintah.

$ 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
sumber
2
setsebagai cara untuk mengatur opsi tidak di shell Unix asli, itu diperkenalkan oleh shell Bourne di akhir 70-an. set -o nameitu sendiri ditambahkan kemudian oleh shell Korn, ditentukan tetapi opsional dalam POSIX, masih belum didukung oleh versi "modern" dari shell Bourne seperti /bin/shSolaris 10.
Stéphane Chazelas
5

Dari buku "Linux Shell Scripting with Bash", hal 63:

Secara historis, setperintah itu digunakan untuk menghidupkan dan mematikan opsi. Dengan bertambahnya jumlah opsi, setmenjadi lebih sulit untuk digunakan karena opsi diwakili oleh kode huruf tunggal. Akibatnya, Bash menyediakan perintah shopt( opsi shell ) untuk mengaktifkan dan menonaktifkan opsi berdasarkan nama alih-alih huruf. Anda dapat mengatur opsi tertentu hanya melalui surat. Yang lain hanya tersedia di bawah shoptperintah. Ini menjadikan pencarian dan pengaturan opsi tertentu sebagai tugas yang membingungkan.

LoMaPh
sumber
3

Sepertinya opsi "set" diwarisi oleh subkulit dan shopt tidak.

pengguna29778
sumber
Tangkapan bagus. Saya bertanya-tanya apakah ini pilihan yang disengaja atau efek samping.
Kevin
2
@ user29778 Setidaknya di bawah bash 4.1.5 (1) opsi yang diset dengan settidak diwariskan oleh subkulit. Keduanya setdan shoptopsi tidak diwarisi oleh subkulit.
Martin
Bisakah Anda menunjukkan dokumentasi yang menggambarkan karakteristik pewarisan keduanya setdan shopt?
Felipe Alvarez
9
Baik set -odan shoptopsi diwarisi oleh subkulit ( (...),, $(...)komponen pipa). Apakah mereka diwarisi oleh bashdoa lain tergantung pada apakah SHELLOPTSatau BASHOPTStidak di lingkungan atau tidak.
Stéphane Chazelas
0

setberasal dari shell bourne (sh) dan merupakan bagian dari standar POSIX, shoptnamun tidak dan spesifik bourne-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

$ 
sja
sumber