Я буду дотримуватися сценаріїв. Багаті інтерактивні функції (видання командного рядка, завершення, підказки тощо), як правило, дуже відрізняються, досягаючи подібних ефектів абсолютно несумісними способами. Які особливості є у zsh та відсутні у bash, чи навпаки? дає кілька покажчиків на інтерактивне використання.
Найближчим до баша буде ATT ksh93 або mksh (оболонка Корна та клон). Zsh також має підмножину функцій, але вам потрібно запустити його в режимі емуляції ksh, а не в рідному режимі zsh.
Я не перелічу функції POSIX (які доступні в будь-якій сучасній shоболонці), ні відносно незрозумілі функції, ні як зазначені вище функції для інтерактивного використання. Спостереження є дійсними на основі баш 4.2, кш 93u та мкш 40.9.20120630, як виявлено на Debian wheezy.
$'…'(буквальні рядки з зворотною косою інтерполяцією) доступний у ksh93 та mksh. `$"… "(Перекладені рядки) є специфічними для bash.
Mksh і ksh93 повинні ;&пройти через caseзаяву, але не ;;&перевіряти наступні випадки. Mksh має ;|для цього, і останні mksh дозволяє ;;&сумісність.
((…))арифметичні вирази та [[ … ]]тести - це ksh особливості. Деякі умовні оператори різні, див. «Умовні вирази» нижче.
У Ksh і bash є спільні процеси, але вони працюють по-різному.
Mksh та ksh93 підтримують function name {…}синтаксис для визначення функцій на додаток до стандартних name () {…}, але, використовуючи functionв ksh зміни правил визначення, тому дотримуйтесь name () …сумісності. Правила дозволених символів у назвах функцій різняться; дотримуватися буквено-цифрових і _.
Ksh93 і mksh підтримують розширення дужок {foo,bar}. Ksh93 підтримує числові діапазони, {1..42}але mksh - ні.
Ksh93 і МКШ підтримка витягання підрядка з ${VAR:offset}і ${VAR:offset:length}, але не випадок складання , як ${VAR^}, ${VAR,}і т.д. Ви можете зробити перетворення випадок з typeset -lі typeset -uв обох Баш і KSH.
Вони підтримують заміну на ${VAR/PATTERN/STRING}або ${VAR/PATTERN//STRING}. Правила котирування для STRING дещо відрізняються, тому уникайте зворотних косих рядків (а може бути й інших символів) у STRING (побудуйте змінну та використовуйте ${VAR/PATTERN/$REPLACEMENT}натомість, якщо заміна містить символи, що цитують).
Розширення Array ( ${ARRAY[KEY]}, "${ARRAY[@]}", ${#ARRAY[@]}, ${!ARRAY[@]}) робота в Баш як в KSH.
${!VAR}розширюється до того, ${OTHERVAR}коли значення VARis OTHERVAR(непряма посилання на змінну) є специфічним для bash (ksh робить щось інше з ${!VAR}). Щоб отримати це подвійне розширення в ksh, вам потрібно використовувати посилання на ім’я замість ( typeset -n VAR=OTHERVAR; echo "$VAR"). ${!PREFIX*}працює так само.
Підстановка процесів <(…)і >(…)підтримується в ksh93 , але не в МКШ.
Ksh-розширені глобальні шаблони, які потрібно shopt -s extglobактивувати в bash, завжди доступні в ksh93 та mksh.
Mksh не підтримує класи символів, як [[:alpha:]].
Bash і ksh93 визначають псевдофайли і , але mksh не робить./dev/tcp/HOST/PORT/dev/udp/HOST/PORT
Розширення шаблонів під час переадресації в сценаріях (як у var="*.txt"; echo hello >$aписьмовій формі, a.txtякщо це ім'я файлу є єдиним збігом для шаблону) є специфічною для bash особливістю (інші оболонки ніколи цього не роблять у скриптах).
<<< тут-струни працюють в ksh як у bash.
Ярлик >&для перенаправлення помилок синтаксису також підтримується mksh, але не ksh93.
[[ … ]] синтаксис подвійної дужки
Синтаксис подвійної дужки з ksh підтримується як ATT ksh93, так і mksh, як у bash.
Файлові оператори
Ksh93, mksh та bash підтримують однакові розширення до POSIX, включаючи -aяк застарілий синонім -e, -k(липкий), -G(належить egid), -O(власник euid), -ef(той самий файл), -nt(новіший за), -ot(старший за).
-N FILE (змінено з моменту останнього читання) mksh не підтримується.
Mksh не має оператора відповідності регулярного виразу =~. У Ksh93 є цей оператор, і він виконує ті ж відповідність, що і в bash, але не має еквіваленту BASH_REMATCHдля отримання відповідних груп згодом.
Строкові оператори
Ksh93 і mksh підтримують ті ж оператори порівняння рядків, що <і >bash, а також ==синонім =. Mksh не використовує параметри локалі для визначення лексикографічного порядку, він порівнює рядки як рядки байтів.
Інші оператори
-v VARперевірити, чи визначена змінна базова. У будь-якій оболонці POSIX ви можете використовувати [ -z "${VAR+1}" ].
Набір дозволених символів у псевдонімах не однаковий у всіх оболонках. Я думаю, це те саме, що і для функцій (див. Вище).
Ksh93 має вбудовану назву builtin, але вона не виконує ім'я як вбудовану команду. Використовувати commandдля обходу псевдонімів та функцій; це викликає вбудований, якщо такий існує, інакше зовнішня команда (ви можете цього уникнути PATH= command error_out_if_this_is_not_a_builtin).
Це специфічно для bash. Ви можете отримати подібний ефект .sh.fun, .sh.fileі .sh.linenoв ksh93. У mksh нарешті LINENO.
declare- специфічна для bash ім'я для bash typeset. Використання typeset: він також працює в базі.
Mksh визначає localяк псевдонім для typeset. У ksh93 вам потрібно використовувати typeset(або визначити псевдонім).
У Mksh немає асоціативних масивів (вони призначені для ще не виданої версії).
Я не думаю, що typeset -tв ksh є точний еквівалент bash's (функція сліду).
Ksh93 не має -e.
Ksh93 і mksh обробляють -eі -nпараметри, як у bash. Mksh також розуміє -E, ksh93 не сприймає це як варіант. Розширення зворотної косої лінії вимкнено за замовчуванням у ksh93, за замовчуванням у mksh
Ksh не забезпечує спосіб відключення вбудованих команд. Щоб уникнути вбудованого пошуку, знайдіть шлях зовнішньої команди та явно попросіть її.
Ksh93 має, -aале ні -l. Мкш не має жодного.
Ні ksh93, ні mksh не мають export -n. Використовуйте typeset +x fooзамість цього, він працює в bash та ksh.
Ksh не експортує функції через навколишнє середовище.
let те саме в bash і ksh.
Це базова особливість. Ви можете використовувати 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 завжди друкує до стандартного виводу.
Кілька варіантів є специфічними для башти, включаючи всі, що стосуються функції перегляду рядків. Варіанти -r, -d, -n, -N, -t, -uідентичні в Баш, ksh93 і МКШ.
Ви можете оголосити змінну як лише для читання в Ksh93 та mksh з тим же синтаксисом. Якщо змінна є масивом, вам потрібно призначити її спочатку, а потім зробити її лише для читання readonly VAR. Функції не можна зробити лише для читання в ksh.
Усі опції для setта set -oє функціями POSIX або ksh.
shoptє специфічним для bash. Багато варіантів стосуються інтерактивного використання. Про ефекти на глобалізацію та інші функції, включені деякими параметрами, див. Розділ "Параметри" нижче.
Цей варіант .існує і в ksh. У bash та mksh sourceшукає поточний каталог після PATH, але в ksh93 - це точний еквівалент ..
DEBUGПсевдо-сигнал не реалізований в МКШ. У ksh93 існує інший спосіб повідомляти інформацію, детальну інформацію див. У посібнику.
У ksh, typeце псевдонім для whence -v. У mksh type -pне друкується шлях до виконуваного файлу, але читається людиною повідомлення; вам потрібно використовувати whence -p COMMANDзамість цього.
Параметри
shopt -s dotglob - не ігноруйте крапкові файли в глобусі
Для емуляції dotglobпараметра в ksh93 ви можете встановити FIGNORE='@(.|..)'. Я не думаю, що в mksh є щось подібне.
shopt -s extglob - ksh розширені глобальні візерунки
Цей extglobпараметр ефективно завжди включений у ksh.
shopt -s failglob - помилка, якщо глобальний зразок нічого не відповідає
Я не думаю, що це існує ні в mksh, ні в ksh93. Це робиться в zsh (поведінка за замовчуванням, якщо не встановлено null_globабо csh_null_glob).
Ksh93 має рекурсивний глобул **/, увімкнено за допомогою set -G. Mksh не має рекурсивного глобулювання.
shopt -s lastpipe - запустити останню команду конвеєра в батьківській оболонці
Ksh93 завжди виконує останню команду конвеєра в батьківській оболонці, яка в bash вимагає встановлення lastpipeпараметра. Mksh завжди виконує останню команду конвеєра в підпакеті.
shopt -s nocaseglob, shopt -s nocasematch- нечутливі до регістру моделі
Mksh не відповідає нечутливому до регістру шаблону. Ksh93 підтримує його на основі шаблону: за допомогою префікса ~(i).
shopt -s nullglob - розширити шаблони, які не відповідають жодному файлу, до порожнього списку
У Mksh цього немає. Ksh93 підтримує його на основі шаблону: за допомогою префікса ~(N).
Очевидно, що більшість BASH_xxxзмінних не існує в ksh. $BASHPIDможе бути емульовано дорогим, але портативним sh -c 'echo $PPID', і нещодавно додано в mksh. BASH_LINEє .sh.linenoв кш93 та LINENOв мкш. BASH_SUBSHELLзнаходиться .sh.subshellв ksh93.
Mksh та ksh93 обидва джерела передають файл, який ENVвони дають при запуску.
EUIDі UIDне існують у ksh93. Mksh називає їх USER_IDі KSH_UID; цього не має GROUPS.
FUNCNAMEі FUNCNESTне існують в ksh. Кш93 має .sh.funі .sh.level. Функції, оголошені function foo { …; }(без дужок!), Мають власне ім'я $0.
GLOBIGNOREіснує в ksh93, але з іншою назвою та синтаксисом: він називається FIGNORE, і це єдиний шаблон, а не розділений двокрапкою список. Використовуйте @(…|…)візерунок. Ksh's subshes FIGNOREbash's, що має зовсім інший синтаксис.
Ksh93 і mksh не мають нічого подібного HOSTTYPE, MACHTYPEі OSTYPE. Ні SHELLOPTSабо TIMEFORMAT.
Mksh має PIPESTATUS, але ksh93 ні.
Mksh і ksh93 мають RANDOM.