Sejauh mana cangkang kompatibel POSIX lainnya berfungsi sebagai pengganti yang wajar untuk bash? Mereka tidak perlu menjadi pengganti "drop-in" yang sebenarnya, tetapi cukup dekat untuk bekerja dengan sebagian besar skrip dan mendukung sisanya dengan beberapa modifikasi.
Saya ingin memiliki skrip bash eksplisit - skrip init, skrip klien DHCP, dll. - bekerja dengan modifikasi minimal
Saya ingin koleksi skrip shell saya yang lebih khusus tidak perlu terlalu banyak modifikasi
Saya ingin memiliki fitur seperti manipulasi string dan pencocokan pola regex bawaan
Satu-satunya pesaing serius yang saya tahu adalah zsh dan mksh. Jadi, bagi Anda di sini yang baik dengan salah satu atau keduanya:
Fitur apa yang dimiliki bash yang tidak dimiliki zsh dan mksh?
Fitur apa yang digunakan shell untuk menggunakan bash, tetapi gunakan sintaks yang tidak kompatibel?
bash
, mksh dan zsh dapat berfungsi seperti/bin/sh
berbagai tingkat kebenaran, tetapi tidakbash
.Jawaban:
Saya akan tetap menggunakan fitur scripting. Fitur-fitur interaktif yang kaya (edisi baris perintah, penyelesaian, konfirmasi, dll.) Cenderung sangat berbeda, mencapai efek yang sama dengan cara yang sepenuhnya tidak kompatibel. Fitur apa yang ada di zsh dan hilang dari bash, atau sebaliknya? memberikan beberapa petunjuk tentang penggunaan interaktif.
Hal terdekat dengan bash adalah ATT ksh93 atau mksh (shell Korn dan klon). Zsh juga memiliki subset fitur, tetapi Anda harus menjalankannya dalam mode emulasi ksh, bukan dalam mode asli zsh.
Saya tidak akan mencantumkan fitur POSIX (yang tersedia di
sh
shell modern ), atau fitur yang relatif tidak jelas, atau seperti yang disebutkan di atas untuk penggunaan interaktif. Pengamatan valid pada bash 4.2, ksh 93u dan mksh 40.9.20120630 seperti yang ditemukan di Debian wheezy.Sintaks shell
Mengutip
$'…'
(string literal dengan interpolasi backslash) tersedia dalam ksh93 dan mksh. `$" ... "(string yang diterjemahkan) adalah khusus untuk bash.Konstruksi bersyarat
Mksh dan ksh93 harus
;&
melaluicase
pernyataan, tetapi tidak;;&
untuk menguji kasus selanjutnya. Mksh memiliki;|
untuk itu, dan mksh baru-baru ini memungkinkan;;&
untuk kompatibilitas.((…))
ekspresi dan[[ … ]]
tes aritmatika adalah fitur ksh. Beberapa operator kondisional berbeda, lihat “ekspresi kondisional” di bawah.Proses ulang
Ksh dan bash keduanya memiliki proses ulang tetapi mereka bekerja secara berbeda.
Fungsi
Mksh dan ksh93 mendukung
function name {…}
sintaks untuk definisi fungsi di samping standarname () {…}
, tetapi menggunakanfunction
dalam ksh mengubah aturan pelingkupan, jadi pertahankanname () …
untuk menjaga kompatibilitas. Aturan untuk karakter yang diizinkan dalam nama fungsi bervariasi; tetap menggunakan alfanumerik dan_
.Ekspansi penjepit
Ksh93 dan mksh mendukung ekspansi brace
{foo,bar}
. Ksh93 mendukung rentang numerik{1..42}
tetapi mksh tidak.Ekspansi parameter
Ksh93 dan mksh dukungan ekstraksi substring dengan
${VAR:offset}
dan${VAR:offset:length}
, tetapi tidak terjadi lipat seperti${VAR^}
,${VAR,}
, dll Anda dapat melakukan konversi kasus dengantypeset -l
dantypeset -u
di kedua bash dan ksh.Mereka mendukung penggantian dengan
${VAR/PATTERN/STRING}
atau${VAR/PATTERN//STRING}
. Aturan kutip untuk STRING sedikit berbeda, jadi hindari garis miring terbalik (dan mungkin karakter lain) di STRING (buat variabel dan gunakan${VAR/PATTERN/$REPLACEMENT}
sebagai gantinya jika pengganti berisi karakter kutip).Ekspansi Array (
${ARRAY[KEY]}
,"${ARRAY[@]}"
,${#ARRAY[@]}
,${!ARRAY[@]}
) bekerja di bash seperti di ksh.${!VAR}
meluas ke${OTHERVAR}
saat nilaiVAR
isOTHERVAR
(referensi variabel tidak langsung) spesifik-bash (ksh melakukan sesuatu yang berbeda dengan${!VAR}
). Untuk mendapatkan ekspansi ganda dalam ksh, Anda harus menggunakan referensi nama sebagai gantinya (typeset -n VAR=OTHERVAR; echo "$VAR"
).${!PREFIX*}
bekerja sama.Substitusi proses
Proses substitusi
<(…)
dan>(…)
didukung dalam ksh93 tetapi tidak dalam mksh.Pola wildcard
Pola ksh extended glob yang perlu
shopt -s extglob
diaktifkan dalam bash selalu tersedia di ksh93 dan mksh.Mksh tidak mendukung kelas karakter seperti
[[:alpha:]]
.Pengalihan IO
Bash dan ksh93 mendefinisikan pseudo-file dan , tetapi mksh tidak.
/dev/tcp/HOST/PORT
/dev/udp/HOST/PORT
Memperluas wildcard dalam pengalihan dalam skrip (seperti dalam
var="*.txt"; echo hello >$a
penulisana.txt
jika nama file itu satu-satunya yang cocok dengan pola) adalah fitur khusus bash (shell lain tidak pernah melakukannya dalam skrip).<<<
di sini-string bekerja di ksh seperti di bash.Jalan pintas
>&
untuk mengarahkan ulang kesalahan sintaks juga didukung oleh mksh tetapi tidak oleh ksh93.Ekspresi bersyarat
[[ … ]]
sintaks braket gandaSintaks braket ganda dari ksh didukung oleh ATT ksh93 dan mksh seperti pada bash.
Operator file
Ksh93, mksh dan bash mendukung ekstensi yang sama untuk POSIX, termasuk
-a
sebagai sinonim usang-e
,-k
(sticky),-G
(dimiliki oleh egid),-O
(pemilik oleh euid),-ef
(file yang sama),-nt
(lebih baru dari),-ot
(lebih tua dari).-N FILE
(dimodifikasi sejak baca terakhir) tidak didukung oleh mksh.Mksh tidak memiliki operator pencocokan regexp
=~
. Ksh93 memiliki operator ini, dan melakukan pencocokan yang sama seperti di bash, tetapi tidak memiliki yang setara denganBASH_REMATCH
untuk mengambil grup yang cocok setelahnya.Operator string
Ksh93 dan mksh mendukung operator perbandingan string yang sama
<
dan>
juga bash serta==
sinonim dari=
. Mksh tidak menggunakan pengaturan lokal untuk menentukan urutan leksikografis, ia membandingkan string sebagai string byte.Operator lain
-v VAR
untuk menguji apakah suatu variabel didefinisikan spesifik-bash. Di setiap shell POSIX, Anda dapat menggunakan[ -z "${VAR+1}" ]
.Dibangun
alias
Set karakter yang diizinkan dalam nama alias tidak sama di semua shell. Saya pikir itu sama dengan fungsi (lihat di atas).
builtin
Ksh93 memiliki builtin yang dipanggil
builtin
, tetapi tidak menjalankan nama sebagai perintah built-in. Gunakancommand
untuk memotong alias dan fungsi; ini akan memanggil builtin jika ada, jika tidak, perintah eksternal (Anda dapat menghindari ini denganPATH= command error_out_if_this_is_not_a_builtin
).caller
Ini khusus untuk bash. Anda bisa mendapatkan efek serupa dengan
.sh.fun
,.sh.file
dan.sh.lineno
di ksh93. Di mksh akhirnya adaLINENO
.declare
,local
,typeset
declare
adalah nama spesifik-bash untuk kshtypeset
. Gunakantypeset
: ini juga bekerja di bash.Mksh mendefinisikan
local
sebagai alias untuktypeset
. Di ksh93, Anda perlu menggunakantypeset
(atau mendefinisikan alias).Mksh tidak memiliki array asosiatif (mereka dijadwalkan untuk versi yang belum dirilis).
Saya tidak berpikir ada yang sama persis dengan
typeset -t
(fungsi jejak) bash di ksh.cd
Ksh93 tidak punya
-e
.echo
Ksh93 dan mksh memproses
-e
dan-n
opsi seperti di bash. Mksh juga mengerti-E
, ksh93 tidak memperlakukannya sebagai opsi. Ekspansi Backslash dimatikan secara default di ksh93, diaktifkan secara default di mksh.enable
Ksh tidak menyediakan cara untuk menonaktifkan perintah builtin. Untuk menghindari builtin, cari jalur perintah eksternal dan aktifkan secara eksplisit.
exec
Ksh93 memiliki
-a
tetapi tidak-l
. Mksh tidak memiliki keduanya.export
Baik ksh93 maupun mksh tidak
export -n
. Gunakantypeset +x foo
sebagai gantinya, ia bekerja di bash dan ksh.Ksh tidak mengekspor fungsi melalui lingkungan.
let
let
sama di bash dan ksh.mapfile
,readarray
Ini adalah fitur khusus bash. Anda dapat menggunakan
while read
loop atau substitusi perintah untuk membaca file dan membaginya menjadi array baris. JagaIFS
dan globbing. Ini setara denganmapfile -t lines </path/to/file
:printf
printf
sangat mirip. Saya pikir ksh93 mendukung semua arahan format bash. mksh tidak mendukung%q
atau%(DATE_FORMAT)T
; pada beberapa instalasi,printf
bukan mksh builtin dan memanggil perintah eksternal sebagai gantinya.printf -v VAR
spesifik-bash, ksh selalu mencetak ke output standar.read
Beberapa opsi spesifik untuk bash, termasuk semua opsi tentang readline. Pilihan
-r
,-d
,-n
,-N
,-t
,-u
identik di bash, ksh93 dan mksh.readonly
Anda bisa mendeklarasikan variabel sebagai read-only di Ksh93 dan mksh dengan sintaks yang sama. Jika variabelnya adalah array, Anda harus menetapkannya terlebih dahulu, kemudian membuatnya hanya-baca
readonly VAR
. Fungsi tidak dapat dibuat hanya-baca dalam ksh.set
,shopt
Semua opsi ke
set
danset -o
merupakan fitur POSIX atau ksh.shopt
spesifik untuk bash. Banyak pilihan yang menyangkut penggunaan interaktif. Untuk efek pada penggumpalan dan fitur lain yang diaktifkan oleh beberapa opsi, lihat bagian "Opsi" di bawah ini.source
Varian ini
.
ada di ksh juga. Di bash dan mksh,source
cari direktori saat ini setelahnyaPATH
, tetapi di ksh93, ini persis sama dengan.
.trap
The
DEBUG
pseudo-sinyal tidak dilaksanakan di mksh. Di ksh93, ia ada dengan cara berbeda untuk melaporkan informasi, lihat manual untuk detailnya.type
Di ksh,
type
adalah alias untukwhence -v
. Di mksh,type -p
tidak mencetak path ke executable, tetapi pesan yang bisa dibaca manusia; Anda harus menggunakannyawhence -p COMMAND
sebagai gantinya.Pilihan
shopt -s dotglob
- jangan abaikan file dot di globbingUntuk meniru
dotglob
opsi dalam ksh93, Anda dapat mengaturFIGNORE='@(.|..)'
. Saya tidak berpikir ada yang seperti ini di mksh.shopt -s extglob
- ksh diperpanjang pola gumpalanThe
extglob
pilihan adalah efektif selalu di ksh.shopt -s failglob
- Kesalahan jika pola glob tidak cocok dengan apa punSaya tidak berpikir ini ada di mksh atau ksh93. Itu dalam zsh (perilaku default kecuali
null_glob
ataucsh_null_glob
diatur).shopt -s globstar
-**/
globbing rekursifKsh93 memiliki globbing rekursif dengan
**/
, diaktifkan denganset -G
. Mksh tidak memiliki globbing rekursif.shopt -s lastpipe
- Jalankan perintah terakhir dari sebuah pipa di shell indukKsh93 selalu menjalankan perintah terakhir dari sebuah pipeline di shell induk, yang dalam bash membutuhkan
lastpipe
opsi untuk diatur. Mksh selalu menjalankan perintah terakhir dari sebuah pipa dalam sebuah subkulit.shopt -s nocaseglob
,shopt -s nocasematch
- pola case-insensitiveMksh tidak memiliki pencocokan pola case-insensitive. Ksh93 mendukungnya berdasarkan pola-demi-pola: awali pola dengan
~(i)
.shopt -s nullglob
- perluas pola yang tidak cocok dengan file ke daftar kosongMksh tidak punya ini. Ksh93 mendukungnya berdasarkan pola-demi-pola: awali pola dengan
~(N)
.Variabel
Jelas sebagian besar
BASH_xxx
variabel tidak ada di ksh.$BASHPID
dapat ditiru dengan mahal tapi portabelsh -c 'echo $PPID'
, dan baru-baru ini ditambahkan ke mksh.BASH_LINE
ada.sh.lineno
di ksh93 danLINENO
di mksh.BASH_SUBSHELL
ada.sh.subshell
di ksh93.Mksh dan ksh93 keduanya sumber file yang diberikan
ENV
ketika mereka memulai.EUID
danUID
tidak ada di ksh93. Mksh memanggil merekaUSER_ID
danKSH_UID
; tidak adaGROUPS
.FUNCNAME
danFUNCNEST
tidak ada di ksh. Ksh93 memiliki.sh.fun
dan.sh.level
. Fungsi yang dideklarasikan denganfunction foo { …; }
(tanpa tanda kurung!) Memiliki nama sendiri di$0
.GLOBIGNORE
ada di ksh93 tetapi dengan nama dan sintaks yang berbeda: itu disebutFIGNORE
, dan itu adalah pola tunggal, bukan daftar yang dipisahkan titik dua. Gunakan@(…|…)
pola. KshFIGNORE
mengelompokkan bash, dengan sintaks yang sama sekali berbeda.Ksh93 dan mksh tidak ada yang suka
HOSTTYPE
,MACHTYPE
danOSTYPE
. AtauSHELLOPTS
atauTIMEFORMAT
.Mksh punya
PIPESTATUS
, tapi ksh93 tidak.Mksh dan ksh93 miliki
RANDOM
.sumber
$BASHPID
ditirush -c 'echo $PPID'
? Saya mencoba(sh -c 'echo $PPID')
di Bash tetapi memberi saya PID yang sama dengan$$
.Pertanyaan ini agak terlalu luas.
Baik mksh dan zsh adalah shell yang mendukung banyak ekstensi GNU bash -specific, tetapi selalu ada beberapa yang tidak dimengerti.
zsh mendukung lebih banyak hal, tetapi hanya dalam mode zsh aslinya, yang tidak kompatibel dengan shell POSIX (seperti GNU bash, AT&T ksh93 , mksh). Juga, mksh jauh lebih ramping dan lebih cepat dan lebih portabel.
Secara umum, jika ini adalah skrip Anda yang sedang kita bicarakan, silakan, coba saja. (mksh belum mendukung array asosiatif bash4-style. Perintah "mendeklarasikan" adalah spesifik-bash, "typeset" adalah setara. Saya tidak cukup familiar dengan zsh untuk menyatakan apa pun tentang hal itu secara langsung. ksh93 tidak memiliki "lokal" tetapi juga menggunakan "typeset" untuk itu.) Tetapi jika ini tentang, katakanlah, menjalankan sistem Debian kurang-bash, lupakan saja. Keberadaan bash adalah bagian dari "janji" (API / ABI sistem), dan banyak yang bergantung padanya.
Penafian: Saya adalah pengembang mksh.
sumber
ZSH Perbandingan Kerang
Saya paling tidak terbiasa dengan mksh, jadi saya tidak tahu ke mana harus mencari jawaban itu.
Jika Anda mencari pengganti shell yang aman, tidak ada shell yang berbeda jauh dari Bash sejauh cacat bawaan yang Anda diskusikan.
Bahasa seperti Perl menangani input dengan lebih aman. Tetapi perawatan juga merupakan kunci di sini. Penggantian shell Perl tidak diadopsi dengan baik. Merupakan tanggung jawab pengelola shell untuk menangani input dengan aman. Jadi ketika Anda menulis skrip, validasi, validasikan, validasi semuanya! Gunakan kontrak kode untuk memastikan hasil yang benar setiap waktu!
Perl Shell
Pernyataan FSF tentang Shell Shock
sumber
Salah satu fitur yang tidak diaktifkan secara default
mksh
adalah riwayat shell.Di
.mkshrc
set hanya Anda :export HISTFILE=~/.mksh-history
sumber