Я буду придерживаться скриптовых функций. Богатые интерактивные функции (редактирование командной строки, завершение, подсказки и т. Д.), Как правило, сильно отличаются друг от друга, достигая аналогичных эффектов совершенно несовместимыми способами. Какие функции есть в 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}
когда значение VAR
is 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
.