Tôi sẽ gắn bó với các tính năng kịch bản. Các tính năng tương tác phong phú (phiên bản dòng lệnh, hoàn thành, lời nhắc, v.v.) có xu hướng rất khác nhau, đạt được hiệu ứng tương tự theo những cách hoàn toàn không tương thích. Những tính năng nào trong zsh và thiếu từ bash, hoặc ngược lại? đưa ra một vài gợi ý về việc sử dụng tương tác.
Thứ gần nhất với bash sẽ là ATT ksh93 hoặc mksh (vỏ Korn và một bản sao). Zsh cũng có một tập hợp các tính năng nhưng bạn sẽ cần chạy nó ở chế độ mô phỏng ksh, không phải ở chế độ gốc zsh.
Tôi sẽ không liệt kê các tính năng POSIX (có sẵn trong bất kỳ trình sh
bao hiện đại nào ), cũng không phải là các tính năng tương đối khó hiểu, cũng như các tính năng được đề cập ở trên để sử dụng tương tác. Các quan sát có giá trị như bash 4.2, ksh 93u và mksh 40.9.20120630 như được tìm thấy trên Debian wheezy.
$'…'
(chuỗi ký tự với nội suy dấu gạch chéo ngược) có sẵn trong ksh93 và mksh. `$" '"(Chuỗi dịch) là đặc trưng bash.
Mksh và ksh93 phải ;&
thông qua một case
tuyên bố, nhưng không ;;&
kiểm tra các trường hợp tiếp theo. Mksh đã ;|
cho điều đó, và mksh gần đây cho phép ;;&
tương thích.
((…))
biểu thức số học và [[ … ]]
kiểm tra là các tính năng ksh. Một số toán tử có điều kiện là khác nhau, hãy xem các biểu thức điều kiện có điều kiện khác bên dưới.
Cả Ksh và bash đều có bộ đồng xử lý nhưng chúng hoạt động khác nhau.
Mksh và ksh93 hỗ trợ function name {…}
cú pháp cho các định nghĩa hàm ngoài tiêu chuẩn name () {…}
, nhưng sử dụng function
trong ksh sẽ thay đổi các quy tắc phạm vi, vì vậy hãy kiên name () …
trì để duy trì khả năng tương thích. Các quy tắc cho các ký tự được phép trong tên hàm khác nhau; dính vào chữ và số _
.
Ksh93 và mksh hỗ trợ mở rộng nẹp {foo,bar}
. Ksh93 hỗ trợ phạm vi số {1..42}
nhưng mksh thì không.
Ksh93 và hỗ trợ chuỗi khai thác mksh với ${VAR:offset}
và ${VAR:offset:length}
, nhưng không phải trường hợp gấp như ${VAR^}
, ${VAR,}
vv Bạn có thể làm chuyển đổi trường hợp typeset -l
và typeset -u
trong cả bash và ksh.
Họ hỗ trợ thay thế bằng ${VAR/PATTERN/STRING}
hoặc ${VAR/PATTERN//STRING}
. Các quy tắc trích dẫn cho STRING hơi khác nhau, do đó, tránh dấu gạch chéo ngược (và có thể các ký tự khác) trong STRING (xây dựng một biến và sử dụng ${VAR/PATTERN/$REPLACEMENT}
thay thế nếu thay thế có chứa các ký tự trích dẫn).
Mảng mở rộng ( ${ARRAY[KEY]}
, "${ARRAY[@]}"
, ${#ARRAY[@]}
, ${!ARRAY[@]}
) làm việc trong bash như trong ksh.
${!VAR}
mở rộng đến ${OTHERVAR}
khi giá trị của VAR
là OTHERVAR
(gián tiếp biến tài liệu tham khảo) là bash cụ thể (ksh làm điều gì đó khác nhau với ${!VAR}
). Để có được mở rộng gấp đôi này trong ksh, bạn cần sử dụng tham chiếu tên thay thế ( typeset -n VAR=OTHERVAR; echo "$VAR"
). ${!PREFIX*}
hoạt động như nhau
Quá trình thay thế <(…)
và >(…)
được hỗ trợ trong ksh93 nhưng không phải trong mksh.
Các mẫu toàn cầu mở rộng ksh cần shopt -s extglob
được kích hoạt trong bash luôn có sẵn trong ksh93 và mksh.
Mksh không hỗ trợ các lớp nhân vật như [[:alpha:]]
.
Bash và ksh93 định nghĩa các tệp giả và , nhưng mksh thì không./dev/tcp/HOST/PORT
/dev/udp/HOST/PORT
Mở rộng các ký tự đại diện để chuyển hướng trong các tập lệnh (như var="*.txt"; echo hello >$a
bằng văn bản a.txt
nếu tên tệp đó là đối sánh duy nhất cho mẫu) là một tính năng dành riêng cho bash (các shell khác không bao giờ thực hiện trong các tập lệnh).
<<<
chuỗi ở đây hoạt động trong ksh như trong bash.
Phím tắt >&
để chuyển hướng lỗi cú pháp cũng được hỗ trợ bởi mksh nhưng không phải bởi ksh93.
[[ … ]]
cú pháp ngoặc kép
Cú pháp ngoặc kép từ ksh được hỗ trợ bởi cả ATT ksh93 và mksh như trong bash.
Toán tử tập tin
Ksh93, mksh và hỗ trợ bash các phần mở rộng cùng với POSIX, bao gồm -a
như một từ đồng nghĩa lỗi thời của -e
, -k
(dính), -G
(thuộc sở hữu của egid), -O
(chủ sở hữu bởi euid), -ef
(cùng một tập tin), -nt
(mới hơn), -ot
(lớn hơn).
-N FILE
(sửa đổi từ lần đọc trước) không được mksh hỗ trợ.
Mksh không có toán tử khớp regrec =~
. Ksh93 có toán tử này và nó thực hiện tương tự như trong bash, nhưng sau đó không có tương đương BASH_REMATCH
để truy xuất các nhóm khớp.
Toán tử chuỗi
Ksh93 và mksh hỗ trợ các toán tử so sánh chuỗi giống nhau <
và >
như bash cũng như ==
từ đồng nghĩa của =
. Mksh không sử dụng cài đặt ngôn ngữ để xác định thứ tự từ điển, nó so sánh các chuỗi như chuỗi byte.
Các nhà khai thác khác
-v VAR
để kiểm tra nếu một biến được định nghĩa là đặc trưng bash. Trong bất kỳ vỏ POSIX, bạn có thể sử dụng [ -z "${VAR+1}" ]
.
Tập hợp các ký tự được phép trong các tên bí danh không giống nhau trong tất cả các shell. Tôi nghĩ nó giống như cho các chức năng (xem ở trên).
Ksh93 có một lệnh dựng sẵn builtin
, nhưng nó không thực thi tên dưới dạng lệnh tích hợp. Sử dụng command
để bỏ qua các bí danh và chức năng; cái này sẽ gọi hàm dựng sẵn nếu có, nếu không thì lệnh bên ngoài (bạn có thể tránh điều này với PATH= command error_out_if_this_is_not_a_builtin
).
Đây là bash cụ thể. Bạn có thể nhận được một hiệu ứng tương tự với .sh.fun
, .sh.file
và .sh.lineno
trong ksh93. Trong mksh cuối cùng cũng có LINENO
.
declare
là một tên riêng của bash cho ksh's typeset
. Sử dụng typeset
: nó cũng hoạt động trong bash.
Mksh định nghĩa local
như một bí danh cho typeset
. Trong ksh93, bạn cần sử dụng typeset
(hoặc xác định bí danh).
Mksh không có mảng kết hợp (chúng được dự kiến là phiên bản chưa được phát hành).
Tôi không nghĩ rằng có một tương đương chính xác của bash's typeset -t
(hàm theo dõi) trong ksh.
Ksh93 không có -e
.
Ksh93 và mksh xử lý các tùy chọn -e
và -n
như trong bash. Mksh cũng hiểu -E
, ksh93 không coi đó là một lựa chọn. Mở rộng dấu gạch chéo ngược được tắt theo mặc định trong ksh93, theo mặc định trong mksh.
Ksh không cung cấp cách để vô hiệu hóa các lệnh dựng sẵn. Để tránh tích hợp sẵn, hãy tìm đường dẫn của lệnh bên ngoài và gọi nó một cách rõ ràng.
Ksh93 có -a
nhưng không -l
. Mksh không có.
Cả ksh93 và mksh đều không có export -n
. Sử dụng typeset +x foo
thay thế, nó hoạt động trong bash và ksh.
Ksh không xuất các chức năng thông qua môi trường.
let
là giống nhau trong bash và ksh.
Đây là một tính năng cụ thể bash. Bạn có thể sử dụng while read
các vòng lặp hoặc thay thế lệnh để đọc một tệp và chia nó thành một mảng các dòng. Hãy chăm sóc IFS
và Globing. Đây là tương đương với mapfile -t lines </path/to/file
:
IFS=$'\n'; set -f
lines=($(</path/to/file))
unset IFS; set +f
printf
rất giống nhau Tôi nghĩ rằng ksh93 hỗ trợ tất cả các chỉ thị định dạng của bash. mksh không hỗ trợ %q
hoặc %(DATE_FORMAT)T
; trên một số cài đặt, printf
không phải là một mksh dựng sẵn và thay vào đó gọi lệnh bên ngoài.
printf -v VAR
là đặc trưng của bash, ksh luôn in ra đầu ra tiêu chuẩn.
Một số tùy chọn là dành riêng cho bash, bao gồm tất cả các tùy chọn về đường dẫn. Các tùy chọn -r
, -d
, -n
, -N
, -t
, -u
là giống hệt nhau trong bash, ksh93 và mksh.
Bạn có thể khai báo một biến là chỉ đọc trong Ksh93 và mksh với cùng một cú pháp. Nếu biến là một mảng, bạn cần gán cho nó trước, sau đó làm cho nó chỉ đọc với readonly VAR
. Các chức năng không thể được thực hiện chỉ đọc trong ksh.
Tất cả các tùy chọn đến set
và set -o
là các tính năng POSIX hoặc ksh.
shopt
là bash cụ thể. Nhiều lựa chọn liên quan đến việc sử dụng tương tác nào. Để biết các hiệu ứng trên toàn cầu và các tính năng khác được kích hoạt bởi một số tùy chọn, hãy xem phần Tùy chọn liên kết bên dưới.
Biến thể này .
tồn tại trong ksh là tốt. Trong bash và mksh, source
tìm kiếm thư mục hiện tại sau PATH
, nhưng trong ksh93, nó tương đương chính xác .
.
Các DEBUG
giả tín hiệu không được thực hiện trong mksh. Trong ksh93, nó tồn tại với một cách khác để báo cáo thông tin, xem hướng dẫn để biết chi tiết.
Trong ksh, type
là một bí danh cho whence -v
. Trong mksh, type -p
không in đường dẫn đến tệp thực thi, mà là một thông điệp có thể đọc được; bạn cần sử dụng whence -p COMMAND
thay thế
Tùy chọn
shopt -s dotglob
- đừng bỏ qua các tập tin dấu chấm trong globalbing
Để mô phỏng dotglob
tùy chọn trong ksh93, bạn có thể đặt FIGNORE='@(.|..)'
. Tôi không nghĩ có bất cứ điều gì như thế này trong mksh.
Các extglob
tùy chọn có hiệu quả luôn luôn trong ksh.
Tôi không nghĩ rằng điều này tồn tại trong cả mksh hoặc ksh93. Nó thực hiện trong zsh (hành vi mặc định trừ khi null_glob
hoặc csh_null_glob
được đặt).
Ksh93 có tính năng đệ quy đệ quy với **/
, được bật với set -G
. Mksh không có tính năng đệ quy đệ quy.
shopt -s lastpipe
- chạy lệnh cuối cùng của đường ống trong shell cha
Ksh93 luôn chạy lệnh cuối cùng của một đường ống trong shell cha, trong bash yêu cầu lastpipe
tùy chọn được đặt. Mksh luôn chạy lệnh cuối cùng của một đường ống trong một lớp con.
shopt -s nocaseglob
, shopt -s nocasematch
- mẫu không phân biệt chữ hoa chữ thường
Mksh không có kết hợp mẫu không phân biệt chữ hoa chữ thường. Ksh93 hỗ trợ nó trên cơ sở từng mẫu: tiền tố mẫu với ~(i)
.
shopt -s nullglob
- mở rộng các mẫu không khớp với tệp vào danh sách trống
Mksh không có cái này. Ksh93 hỗ trợ nó trên cơ sở từng mẫu: tiền tố mẫu với ~(N)
.
Rõ ràng hầu hết các BASH_xxx
biến không tồn tại trong ksh. $BASHPID
có thể được mô phỏng với chi phí cao nhưng di động sh -c 'echo $PPID'
và gần đây đã được thêm vào mksh. BASH_LINE
là .sh.lineno
trong ksh93 và LINENO
trong mksh. BASH_SUBSHELL
là .sh.subshell
ở ksh93.
Mksh và ksh93 đều nguồn tệp được cung cấp ENV
khi chúng khởi động.
EUID
và UID
không tồn tại trong ksh93. Mksh gọi họ USER_ID
và KSH_UID
; nó không có GROUPS
.
FUNCNAME
và FUNCNEST
không tồn tại trong ksh. Ksh93 có .sh.fun
và .sh.level
. Các hàm được khai báo với function foo { …; }
(không có dấu ngoặc đơn!) Có tên riêng của chúng trong $0
.
GLOBIGNORE
tồn tại trong ksh93 nhưng với một tên và cú pháp khác: nó được gọi FIGNORE
và đó là một mẫu duy nhất, không phải là danh sách được phân tách bằng dấu hai chấm. Sử dụng một @(…|…)
mô hình. Ksh's FIGNORE
subs bash's, với một cú pháp hoàn toàn khác.
Ksh93 và mksh không có gì giống như HOSTTYPE
, MACHTYPE
và OSTYPE
. Cũng không SHELLOPTS
hay TIMEFORMAT
.
Mksh có PIPESTATUS
, nhưng ksh93 thì không.
Mksh và ksh93 có RANDOM
.