Я буду дотримуватися сценаріїв. Багаті інтерактивні функції (видання командного рядка, завершення, підказки тощо), як правило, дуже відрізняються, досягаючи подібних ефектів абсолютно несумісними способами. Які особливості є у 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}
коли значення VAR
is 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 FIGNORE
bash's, що має зовсім інший синтаксис.
Ksh93 і mksh не мають нічого подібного HOSTTYPE
, MACHTYPE
і OSTYPE
. Ні SHELLOPTS
або TIMEFORMAT
.
Mksh має PIPESTATUS
, але ksh93 ні.
Mksh і ksh93 мають RANDOM
.