Я буду придерживаться скриптовых функций. Богатые интерактивные функции (редактирование командной строки, завершение, подсказки и т. Д.), Как правило, сильно отличаются друг от друга, достигая аналогичных эффектов совершенно несовместимыми способами. Какие функции есть в zsh и отсутствуют в bash, или наоборот? дает несколько советов по интерактивному использованию.
Наиболее близким к 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 () …для поддержания совместимости. Правила для разрешенных символов в именах функций различаются; придерживаться буквенно-цифровых символов и _.
Ksh93 и mksh поддерживают расширение скобки {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}когда значение VARis OTHERVAR(косвенная ссылка на переменную) зависит от bash (ksh делает что-то другое с ${!VAR}). Чтобы получить это двойное расширение в ksh, вам нужно использовать ссылку на имя вместо ( typeset -n VAR=OTHERVAR; echo "$VAR"). ${!PREFIX*}работает так же.
Подстановка процесса <(…)и >(…)поддерживается в ksh93, но не в mksh.
Шаблоны расширенного глобуса ksh, которые необходимо shopt -s extglobактивировать в bash, всегда доступны в ksh93 и mksh.
Mksh не поддерживает классы символов, такие как [[:alpha:]].
Bash и ksh93 определяют псевдо-файлы и , но МКШ не делает./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(sticky), -G(принадлежит egid), -O(владелец euid), -ef(тот же файл), -nt(новее чем), -ot(старше чем).
-N FILE (изменено с момента последнего чтения) не поддерживается mksh.
Mksh не имеет оператора соответствия регулярному выражению =~. В Ksh93 есть этот оператор, и он выполняет то же сопоставление, что и в bash, но не имеет эквивалента BASH_REMATCHдля извлечения соответствующих групп впоследствии.
Строковые операторы
Ksh93 и mksh поддерживают одинаковые операторы сравнения строк <и >как bash, так и ==синоним =. Mksh не использует настройки локали для определения лексикографического порядка, он сравнивает строки как строки байтов.
Другие операторы
-v VARпроверить, определена ли переменная, зависит от bash. В любой оболочке 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. В Мкш наконец-то есть LINENO.
declareспецифичное для bash имя для ksh typeset. Использование typeset: это также работает в Bash.
Мкш определяет localкак псевдоним для typeset. В ksh93 вам нужно использовать typeset(или определить псевдоним).
Mksh не имеет ассоциативных массивов (они предназначены для еще не выпущенной версии).
Я не думаю, что есть точный эквивалент bash typeset -t(функция трассировки) в ksh.
Кш93 не имеет -e.
Кш93 и мкш обрабатывают -eи -nварианты как в bash. Mksh также понимает -E, ksh93 не рассматривает это как вариант. Расширение с обратной косой чертой отключено по умолчанию в ksh93, по умолчанию включено в mksh.
Ksh не предоставляет способ отключить встроенные команды. Чтобы избежать встроенного, ищите путь внешней команды и вызывайте ее явно.
Кш93 есть -aно нет -l. Мкш не имеет ни того, ни другого.
Ни 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 и МКШ.
Вы можете объявить переменную только для чтения в 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 - не игнорируйте точечные файлы в globbing
Чтобы эмулировать dotglobопцию в ksh93, вы можете установить FIGNORE='@(.|..)'. Я не думаю, что есть что-то подобное в mksh.
shopt -s extglob - ksh расширенные шаблоны глобуса
Эта extglobопция всегда включена в ksh.
shopt -s failglob - ошибка, если шаблон глобуса ничего не соответствует
Я не думаю, что это существует в mksh или ksh93. Это делается в Zsh (поведение по умолчанию, если null_globили csh_null_globне установлены).
Ksh93 имеет рекурсивное сглаживание с **/включенным с set -G. У Мкша нет рекурсивных шаров.
shopt -s lastpipe - выполнить последнюю команду конвейера в родительской оболочке
Ksh93 всегда запускает последнюю команду конвейера в родительской оболочке, которая в bash требует установки lastpipeопции. Mksh всегда запускает последнюю команду конвейера в подоболочке.
shopt -s nocaseglob, shopt -s nocasematch- модель без учета регистра
У Mksh нет сопоставления с регистром без учета регистра. Ksh93 поддерживает его на основе паттернов: паттерн с префиксом ~(i).
shopt -s nullglob - развернуть шаблоны, которые не соответствуют ни одному файлу, в пустой список
У Мкша этого нет. Ksh93 поддерживает его на основе паттернов: паттерн с префиксом ~(N).
Очевидно, что большинство BASH_xxxпеременных не существует в ksh. $BASHPIDможет эмулироваться с дорогостоящим, но переносимым sh -c 'echo $PPID', и недавно был добавлен в mksh. BASH_LINEесть .sh.linenoв кш93 и LINENOв мкш. BASH_SUBSHELLнаходится .sh.subshellв кш93.
Mksh и ksh93 оба получают файл, указанный ENVпри запуске.
EUIDи UIDне существует в ksh93. Мкш называет их USER_IDи KSH_UID; это не имеет GROUPS.
FUNCNAMEи FUNCNESTне существует в кш. Кш93 имеет .sh.funи .sh.level. Функции, объявленные с function foo { …; }(без скобок!), Имеют собственное имя в $0.
GLOBIGNOREсуществует в ksh93, но с другим именем и синтаксисом: он называется FIGNORE, и это один шаблон, а не разделенный двоеточиями список. Используйте @(…|…)шаблон. Ksh включает в FIGNOREсебя bash с совершенно другим синтаксисом.
Ksh93 и МКШ не имеют ничего подобного HOSTTYPE, MACHTYPEи OSTYPE. Ни SHELLOPTSили TIMEFORMAT.
Мкш имеет PIPESTATUS, но ksh93 нет.
Мкш и кш93 есть RANDOM.