Đặt và Shopt - Tại sao hai?


72

setshoptlà cả hai nội dung shell kiểm soát các tùy chọn khác nhau. Tôi thường quên tùy chọn nào được đặt theo lệnh nào và tùy chọn nào đặt / bỏ cài đặt ( set -o/+o, shopt -s/-u). Tại sao có hai lệnh khác nhau dường như làm cùng một việc (và có các đối số khác nhau để làm như vậy)? Có cách nào dễ dàng / ghi nhớ để nhớ tùy chọn nào đi với lệnh nào không?


6
Hãy thử nhìn vào dòng thứ hai help sethelp shoptđể xác minh rằng ngay cả các tác giả của họ cũng nghĩ rằng họ làm điều tương tự.
l0b0

2
"Thay đổi giá trị của các thuộc tính shell" so với "Thay đổi cài đặt của từng tùy chọn shell".
Kevin

2
Trong Bash 4.1.5 (1), hãy nói "Đặt hoặc bỏ giá trị của các tùy chọn vỏ và tham số vị trí." và "Đặt và bỏ đặt tùy chọn vỏ.", tương ứng.
l0b0

Viết trang web làm cho bạn nhận ra những gì bạn không biết và khiến bạn cố gắng xây dựng mọi thứ theo cách bạn không hiểu sai về những gì bạn cố gắng viết về.
sjas

Câu trả lời:


40

Theo như tôi biết, các set -otùy chọn là những tùy chọn được kế thừa từ các shell kiểu Bourne khác (chủ yếu là ksh), và các shopttùy chọn là những tùy chọn dành riêng cho bash. Không có logic mà tôi biết.


1
Bất kỳ tài liệu cho thấy shoptđược thừa kế?
Felipe Alvarez

8
Chà, có những set -otùy chọn như posix/ physical/ interactive-commentskhông có trong đó ksh, và shoptnhững tùy chọn nằm trong các shell khác bao gồm cả kshmột số like login_shell/ nullglob. Như bạn nói, không có logic. Có lẽ đó là ý tưởng khi bắt đầu (rằng SHELLOPTS sẽ là tiêu chuẩn và BASHOPTS là những người cụ thể bash), nhưng điều đó đã bị mất trên đường đi, và bây giờ nó cuối cùng trở nên khó chịu và một thất bại trong thiết kế UI.
Stéphane Chazelas

22

Sự khác biệt là trong biến môi trường thay đổi được sử dụng bởi bash. Thiết lập với setlệnh kết quả trong $SHELLOPTS. Thiết lập với shoptlệnh kết quả trong $BASHOPTS.


9
Ừ Điều đó thậm chí còn khó hiểu hơn. Bộ não của tôi muốn liên kết shoptvới $ SH ELL OPT S thay vì $ BA SHOPT S.
Bruno Bronosky 22/03/2016


8

Dễ nhưng lạc trong lịch sử. Các setlệnh ban đầu được sử dụng để thay đổi môi trường dòng lệnh của vỏ unix gốc /bin/sh. Sau đó, khi các phiên bản Unix khác nhau phát triển và các hương vị vỏ mới được thêm vào, mọi người nhận ra rằng họ cần phải có thể thay đổi nhiều thứ (môi trường) hơn để giữ cho kịch bản shell tương thích. Lúc đó Bash đã rất phổ biến và thêm sh ell opt ion là cần thiết, giới thiệu shopt.

Bạn thực sự có thể thấy những nỗ lực tính tương thích này trong shoptlệnh.

$ 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

Nhưng không phải trong setlệnh.

$ 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
setnhư một cách để thiết lập các tùy chọn không có trong các shell Unix ban đầu, nó được giới thiệu bởi shell Bourne vào cuối những năm 70. set -o namebản thân nó đã được thêm vào bởi vỏ Korn, được chỉ định nhưng tùy chọn trong POSIX, vẫn không được hỗ trợ bởi các phiên bản "hiện đại" của vỏ Bourne như /bin/shcủa Solaris 10.
Stéphane Chazelas

5

Từ cuốn sách "Linux Shell Scripting with Bash", trang 63:

Về mặt lịch sử, các setlệnh được sử dụng để biến tùy chọn và tắt. Khi số lượng tùy chọn tăng lên, settrở nên khó sử dụng hơn vì các tùy chọn được thể hiện bằng mã ký tự đơn. Do đó, Bash cung cấp lệnh shopt( tùy chọn shell ) để bật và tắt tùy chọn theo tên thay vì chữ cái. Bạn có thể đặt các tùy chọn nhất định chỉ bằng thư. Những người khác chỉ có sẵn theo shoptlệnh. Điều này làm cho việc tìm kiếm và thiết lập một tùy chọn cụ thể là một nhiệm vụ khó hiểu.


3

Có vẻ như các tùy chọn "thiết lập" được kế thừa bởi các mạng con còn cửa hàng thì không.


Bắt đẹp. Tôi tự hỏi liệu đây là một lựa chọn có chủ ý hay tác dụng phụ.
Kevin

2
@ user29778 Ít nhất là theo bash 4.1.5 (1) các tùy chọn được thiết lập setkhông được kế thừa bởi subshells.Both setshoptcác tùy chọn không được kế thừa bởi subshells.
Martin

Bạn có thể chỉ ra tài liệu mô tả các đặc điểm thừa kế của cả hai setshopt?
Felipe Alvarez

9
Cả hai set -oshoptcác tùy chọn được kế thừa bởi các lớp con ( (...),, $(...)các thành phần đường ống). Việc chúng có được thừa hưởng bởi các bashyêu cầu khác hay không phụ thuộc vào việc có SHELLOPTShoặc BASHOPTSở trong môi trường hay không.
Stéphane Chazelas

0

setcó nguồn gốc từ vỏ bourne (sh) và là một phần của tiêu chuẩn POSIX, shopttuy nhiên không phải và là vỏ bourne-again (bash) cụ thể:

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

$ 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.