ฉันจะใช้คุณสมบัติการเขียนสคริปต์ คุณสมบัติอินเทอร์แอคทีฟที่หลากหลาย (รุ่นบรรทัดคำสั่งความสมบูรณ์การแจ้งเตือน ฯลฯ ) มีแนวโน้มที่จะแตกต่างกันมาก คุณลักษณะใดบ้างที่อยู่ใน zsh และหายไปจาก bash หรือในทางกลับกัน ให้ตัวชี้สองสามตัวเกี่ยวกับการใช้แบบโต้ตอบ
สิ่งที่ใกล้เคียงที่สุดในการทุบตีคือATT ksh93หรือmksh (Korn เชลล์และโคลน) Zsh มีชุดย่อยของคุณสมบัติ แต่คุณจะต้องเรียกใช้ในโหมดการจำลอง ksh ไม่ใช่ในโหมดเนทีฟ zsh
ฉันจะไม่แสดงรายการคุณสมบัติPOSIX (ซึ่งมีอยู่ในsh
เชลล์ที่ทันสมัย) หรือคุณลักษณะที่ค่อนข้างคลุมเครือและไม่ได้กล่าวถึงคุณสมบัติข้างต้นสำหรับการใช้แบบโต้ตอบ การสังเกตมีผลตั้งแต่ bash 4.2, ksh 93u และ mksh 40.9.20120630 เท่าที่พบใน Debian wheezy
$'…'
(สตริงตัวอักษรที่มีการแก้ไขแบ็กสแลช) มีอยู่ใน ksh93 และ mksh `$" ... "(สตริงที่แปลแล้ว) เป็นข้อมูลเฉพาะของ bash
Mksh และ ksh93 ต้อง;&
ผ่านไปในcase
แถลงการณ์ แต่ไม่ใช่;;&
เพื่อทดสอบกรณีที่ตามมา Mksh มี;|
ไว้สำหรับสิ่งนั้นและ mksh ล่าสุดอนุญาตให้;;&
ใช้งานร่วมกันได้
((…))
การแสดงออกทางคณิตศาสตร์และ[[ … ]]
การทดสอบเป็นคุณสมบัติ ksh ตัวดำเนินการตามเงื่อนไขบางตัวนั้นแตกต่างกันโปรดดู“ นิพจน์เงื่อนไข” ด้านล่าง
Ksh และ bash ทั้งคู่มีตัวประมวลผลร่วม แต่ทำงานแตกต่างกัน
Mksh และ ksh93 สนับสนุนfunction name {…}
ไวยากรณ์สำหรับคำจำกัดความของฟังก์ชั่นเพิ่มเติมจากมาตรฐานname () {…}
แต่การใช้function
ใน ksh เปลี่ยนกฎการกำหนดขอบเขตดังนั้นควรดำเนินการname () …
เพื่อรักษาความเข้ากันได้ กฎสำหรับอักขระที่อนุญาตในชื่อฟังก์ชันแตกต่างกันไป ติด Alphanumerics _
และ
Ksh93 {foo,bar}
และการขยายตัวรั้งสนับสนุน Ksh93 รองรับช่วงตัวเลข{1..42}
แต่ mksh ไม่รองรับ
Ksh93 และ mksh สนับสนุนการแยกสตริงย่อยด้วย${VAR:offset}
และ${VAR:offset:length}
, แต่ไม่สามารถใช้ตัวพิมพ์เล็กและตัวพิมพ์${VAR^}
ใหญ่${VAR,}
, ฯลฯ คุณสามารถทำการแปลงเคสด้วยtypeset -l
และtypeset -u
ทั้งใน bash และ ksh
พวกเขาสนับสนุนการเปลี่ยนด้วยหรือ${VAR/PATTERN/STRING}
${VAR/PATTERN//STRING}
กฎการอ้างอิงสำหรับ STRING แตกต่างกันเล็กน้อยดังนั้นหลีกเลี่ยงแบ็กสแลช (และอักขระอื่น ๆ ) ใน STRING (สร้างตัวแปรและใช้${VAR/PATTERN/$REPLACEMENT}
แทนหากการแทนที่มีอักขระที่อ้างถึง)
การขยายตัวของ array ( ${ARRAY[KEY]}
, "${ARRAY[@]}"
, ${#ARRAY[@]}
, ${!ARRAY[@]}
) การทำงานในทุบตีเหมือนใน ksh
${!VAR}
การขยายเป็น${OTHERVAR}
เมื่อค่าของVAR
คือOTHERVAR
(การอ้างอิงตัวแปรทางอ้อม) เป็น bash-specific (ksh ทำบางสิ่งที่แตกต่างด้วย${!VAR}
) ในการรับส่วนขยายสองเท่าเป็น ksh คุณต้องใช้การอ้างอิงชื่อแทน ( typeset -n VAR=OTHERVAR; echo "$VAR"
) ${!PREFIX*}
ทำงานเหมือนกัน
การทดแทนกระบวนการ<(…)
และ>(…)
ได้รับการสนับสนุนใน ksh93 แต่ไม่ได้อยู่ใน mksh
รูปแบบวงกลมแบบขยาย ksh ที่ต้องshopt -s extglob
เปิดใช้งานใน bash นั้นมีให้ใน ksh93 และ mksh
Mksh [[:alpha:]]
ไม่สนับสนุนตัวละครคลาสเช่น
Bash และ ksh93 กำหนด pseudo-files และแต่ mksh ไม่ได้/dev/tcp/HOST/PORT
/dev/udp/HOST/PORT
การขยาย wildcards ในการเปลี่ยนทิศทางในสคริปต์ (ตามที่var="*.txt"; echo hello >$a
เขียนไว้a.txt
หากชื่อไฟล์นั้นเป็นการจับคู่ แต่เพียงผู้เดียวสำหรับรูปแบบ) เป็นคุณลักษณะเฉพาะของ bash (เชลล์อื่นไม่เคยทำในสคริปต์)
<<<
here-strings ทำงานเป็น ksh เหมือนทุบตี
ทางลัด>&
ไปยังการเปลี่ยนเส้นทางข้อผิดพลาดทางไวยากรณ์ได้รับการสนับสนุนโดย mksh แต่ไม่ใช่โดย ksh93
[[ … ]]
ไวยากรณ์ของวงเล็บคู่
ไวยากรณ์วงเล็บคู่จาก ksh ได้รับการสนับสนุนทั้ง ATT ksh93 และ mksh เหมือนเป็นทุบตี
ผู้ประกอบการไฟล์
Ksh93, mksh และ bash สนับสนุนส่วนขยายเดียวกันกับ POSIX รวมถึง-a
คำพ้องความหมายที่ล้าสมัยของ-e
, -k
(เหนียว), -G
(เป็นของ egid), -O
(เจ้าของโดย euid), -ef
(ไฟล์เดียวกัน), -nt
(ใหม่กว่า), -ot
(เก่ากว่า)
-N FILE
(แก้ไขตั้งแต่อ่านล่าสุด) ไม่รองรับ mksh
Mksh =~
ไม่ได้มีผู้ประกอบการจับคู่ Ksh93 มีโอเปอเรเตอร์นี้และทำการจับคู่เช่นเดียวกับใน bash แต่ไม่เท่ากับBASH_REMATCH
การดึงกลุ่มที่ตรงกันในภายหลัง
ผู้ประกอบการสตริง
Ksh93 และการสนับสนุน mksh เดียวกันผู้ประกอบการเปรียบเทียบสตริง<
และ>
ทุบตีเช่นเดียวกับคำพ้องความหมายของ==
=
Mksh ไม่ได้ใช้การตั้งค่าตำแหน่งที่ตั้งเพื่อกำหนดลำดับพจนานุกรมโดยเปรียบเทียบสตริงเป็นสตริงไบต์
ผู้ประกอบการอื่น ๆ
-v VAR
เพื่อทดสอบว่ามีการกำหนดตัวแปรเฉพาะ bash หรือไม่ ในเปลือก POSIX [ -z "${VAR+1}" ]
คุณสามารถใช้
ชุดของอักขระที่อนุญาตในชื่อนามแฝงนั้นไม่เหมือนกันในเชลล์ทั้งหมด ฉันคิดว่ามันเหมือนกับฟังก์ชั่น (ดูด้านบน)
Ksh93 มี builtin ที่เรียกว่าbuiltin
แต่มันไม่ได้รันชื่อเป็นคำสั่งในตัว ใช้command
เพื่อหลีกเลี่ยงนามแฝงและฟังก์ชัน สิ่งนี้จะเรียกว่าบิวด์อินถ้ามีอยู่มิฉะนั้นจะมีคำสั่งภายนอก (คุณสามารถหลีกเลี่ยงได้PATH= command error_out_if_this_is_not_a_builtin
)
นี่คือเฉพาะทุบตี คุณจะได้รับผลที่คล้ายกันด้วย.sh.fun
, .sh.file
และ.sh.lineno
ใน ksh93 ใน mksh LINENO
มีที่สุดท้าย
declare
เป็นชื่อที่ทุบตีเฉพาะสำหรับ typeset
ksh ใช้typeset
: มันยังทำงานในทุบตี
Mksh กำหนดเป็นชื่อแทนสำหรับlocal
typeset
ใน ksh93 คุณต้องใช้typeset
(หรือกำหนดนามแฝง)
Mksh ไม่มีอาเรย์เชื่อมโยง (มีกำหนดไว้สำหรับเวอร์ชันที่ยังไม่เผยแพร่
ฉันไม่คิดว่าจะมีค่าเทียบเท่าของ bash's typeset -t
(ฟังก์ชันติดตาม) ในหน่วย ksh
Ksh93 -e
ไม่ได้
Ksh93 และ mksh ประมวลผล-e
และ-n
ตัวเลือกเช่นในทุบตี Mksh เข้าใจ-E
เช่นกัน ksh93 ไม่ถือว่าเป็นตัวเลือก การขยายแบ็กสแลชถูกปิดใช้งานตามค่าเริ่มต้นใน ksh93, โดยค่าเริ่มต้นใน mksh
Ksh ไม่มีวิธีปิดใช้งานคำสั่งในตัว เพื่อหลีกเลี่ยงการ buildin ค้นหาเส้นทางของคำสั่งภายนอกและเรียกใช้อย่างชัดเจน
Ksh93 มีแต่ไม่-a
-l
Mksh ไม่มี
ksh93 หรือ mksh export -n
ไม่มี ใช้typeset +x foo
แทนมันทำงานได้ใน bash และ ksh
Ksh ไม่ส่งออกฟังก์ชั่นผ่านสภาพแวดล้อม
let
เหมือนกันใน bash และ ksh
นี่เป็นคุณลักษณะเฉพาะของ bash คุณสามารถใช้while read
ลูปหรือการทดแทนคำสั่งเพื่ออ่านไฟล์และแยกเป็นอาร์เรย์ของบรรทัด ดูแลIFS
และโค้งมน นี่เทียบเท่ากับmapfile -t lines </path/to/file
:
IFS=$'\n'; set -f
lines=($(</path/to/file))
unset IFS; set +f
printf
คล้ายกันมาก ฉันคิดว่า ksh93 สนับสนุนคำสั่งฟอร์แมตของ bash ทั้งหมด mksh ไม่รองรับ%q
หรือ%(DATE_FORMAT)T
; ในการติดตั้งบางอย่างprintf
ไม่ใช่ mksh ในตัวและเรียกใช้คำสั่งภายนอกแทน
printf -v VAR
เฉพาะ bash, ksh จะพิมพ์ไปยังเอาต์พุตมาตรฐานเสมอ
มีหลายตัวเลือกที่เฉพาะสำหรับ bash รวมถึงตัวเลือกทั้งหมดที่เกี่ยวกับ readline ตัวเลือก-r
, -d
, -n
, -N
, -t
, -u
มีความเหมือนกันในทุบตี ksh93 และ mksh
คุณสามารถประกาศตัวแปรแบบอ่านอย่างเดียวใน Ksh93 และ mksh ด้วยไวยากรณ์เดียวกัน readonly VAR
ถ้าตัวแปรคืออาร์เรย์ที่คุณจะต้องกำหนดให้มันเป็นครั้งแรกแล้วทำให้มันอ่านอย่างเดียวกับ ฟังก์ชั่นไม่สามารถทำเป็นแบบอ่านอย่างเดียวใน ksh
ตัวเลือกทั้งหมดไปยังset
และset -o
เป็นคุณสมบัติ POSIX หรือ ksh
shopt
เฉพาะทุบตี ตัวเลือกมากมายเกี่ยวกับการใช้แบบโต้ตอบอยู่แล้ว สำหรับเอฟเฟกต์เกี่ยวกับ globbing และคุณสมบัติอื่น ๆ ที่เปิดใช้งานโดยตัวเลือกบางตัวให้ดูส่วน“ ตัวเลือก” ด้านล่าง
ตัวแปรนี้.
มีอยู่ใน ksh เช่นกัน ในทุบตีและ mksh, source
ค้นหาไดเรกทอรีปัจจุบันหลังจากที่PATH
แต่ใน ksh93 .
ก็เป็นที่แน่นอนของเทียบเท่า
DEBUG
สัญญาณหลอกไม่ได้ดำเนินการใน mksh ใน ksh93 มันมีอยู่ในวิธีที่แตกต่างกันในการรายงานข้อมูลดูคู่มือสำหรับรายละเอียด
ใน ksh, เป็นนามแฝงสำหรับtype
whence -v
ใน mksh type -p
ไม่พิมพ์พา ธ ไปยังไฟล์ที่เรียกทำงานได้ แต่เป็นข้อความที่มนุษย์อ่านได้ คุณต้องใช้whence -p COMMAND
แทน
ตัวเลือก
shopt -s dotglob
- อย่าเพิกเฉยต่อไฟล์ dot ในรูปแบบต่างๆ
ที่จะเลียนแบบdotglob
ตัวเลือกใน ksh93 FIGNORE='@(.|..)'
คุณสามารถตั้งค่า ฉันไม่คิดว่าจะมีอะไรอย่างนี้ใน mksh
extglob
ตัวเลือกที่มีประสิทธิภาพตลอดเวลาใน ksh
shopt -s failglob
- เกิดข้อผิดพลาดหากรูปแบบกลมตรงกับอะไร
ฉันไม่คิดว่ามีอยู่ใน mksh หรือ ksh93 มันทำใน zsh (พฤติกรรมเริ่มต้นนอกจากnull_glob
หรือcsh_null_glob
มีการตั้งค่า)
Ksh93 มี globbing recursive กับ**/
, set -G
การใช้งานด้วย Mksh ไม่มีการวนซ้ำซ้ำ
shopt -s lastpipe
- รันคำสั่งสุดท้ายของไพพ์ไลน์ในเชลล์พาเรนต์
Ksh93 รันคำสั่งสุดท้ายของไพพ์ไลน์เสมอในพาเรนต์เชลล์ซึ่งใน bash ต้องการlastpipe
ให้ตั้งค่าตัวเลือก Mksh จะเรียกใช้คำสั่งสุดท้ายของไปป์ไลน์ใน subshell เสมอ
Mksh ไม่มีรูปแบบที่ไม่ตรงตามตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก Ksh93 สนับสนุนบนพื้นฐานรูปแบบโดยรูปแบบ: ~(i)
รูปแบบคำนำหน้าด้วย
shopt -s nullglob
- ขยายรูปแบบที่ไม่ตรงกับไฟล์ไปยังรายการว่าง
Mksh ไม่มีสิ่งนี้ Ksh93 สนับสนุนบนพื้นฐานรูปแบบโดยรูปแบบ: ~(N)
รูปแบบคำนำหน้าด้วย
เห็นได้ชัดว่าBASH_xxx
ตัวแปรส่วนใหญ่ไม่มีอยู่ในหน่วย ksh $BASHPID
สามารถลอกเลียนแบบด้วยค่าใช้จ่าย แต่พกพาsh -c 'echo $PPID'
ได้และเพิ่งถูกเพิ่มไปยัง mksh BASH_LINE
อยู่.sh.lineno
ใน ksh93 และLINENO
ใน mksh BASH_SUBSHELL
อยู่.sh.subshell
ใน ksh93
Mksh และ ksh93 ทั้งแหล่งไฟล์ที่กำหนดในENV
เมื่อพวกเขาเริ่มต้นขึ้น
EUID
และUID
ไม่มีอยู่ใน ksh93 Mksh เรียกพวกเขาUSER_ID
และKSH_UID
; GROUPS
มันไม่ได้มี
FUNCNAME
และFUNCNEST
ไม่มีอยู่ใน ksh Ksh93 มีและ.sh.fun
.sh.level
ฟังก์ชั่นประกาศด้วยfunction foo { …; }
(ไม่มีวงเล็บ!) $0
มีชื่อของตัวเองใน
GLOBIGNORE
มีอยู่ใน ksh93 แต่มีชื่อและไวยากรณ์ที่แตกต่าง: มันถูกเรียกใช้FIGNORE
และเป็นรูปแบบเดียวไม่ใช่รายการที่คั่นด้วยโคลอน ใช้@(…|…)
รูปแบบ Ksh's FIGNORE
subsumes bash's พร้อมกับไวยากรณ์ที่แตกต่างกันทั้งหมด
Ksh93 และ mksh ไม่มีอะไรเหมือนHOSTTYPE
, และMACHTYPE
OSTYPE
มิได้หรือSHELLOPTS
TIMEFORMAT
Mksh มีPIPESTATUS
แต่ ksh93 ไม่มี
Mksh และ ksh93 RANDOM
มี