Как я могу безопасно получить версию ksh из сценария ksh?
ksh --version
echo ${.sh.version}
echo $KSH_VERSION
И учитывая правильные обстоятельства, каждый из них работает правильно. Тем не менее, я забочусь о неидеальном случае.
В частности, есть несколько машин, с которыми я работаю, которые имеют более старые версии ksh, которым для моих целей сильно не хватает функциональности. В любом случае, причина, по которой я хочу проверить версию (программно), состоит в том, чтобы увидеть, является ли версия ksh одной из менее способных версий; и если это так, я хочу выполнить ветку с менее удивительным кодом.
Однако на проблемных машинах неспособность оболочки распространяется на проверку версии ...
- Если я попытаюсь
ksh --version
, он ничего не печатает и открывает новый экземплярksh
! Если я попытаюсь
echo ${.sh.version}
,ksh
это воспринимается как синтаксическая ошибка, с которой нельзя отказаться2> /dev/null
.$ echo ${.sh.version} 2> /dev/null ksh: ${.sh.version}: bad substitution
Конечно,
echo $KSH_VERSION
кажется, что он работает нормально - я имею в виду, что он не потерпит крах - хотя на этих машинах он пустой. Кроме того, я видел где-то, чтоKSH_VERSION
установлено толькоpdksh
.
Вопросов:
- Как я могу безопасно проверить версию
ksh
программно? Для моих целей здесь меня не волнует, каков фактический номер версии, просто является ли это устаревшей версиейksh
. - Это
$KSH_VERSION
достаточно хорошо? Я имею в виду, если оно пустое, тоksh
обязательно устаревшая версия? Был ли этот другой форум правильным, чтобы его нельзя было установить даже для более новых версийksh
? - Нет ли способа проверить это вообще?
источник
PS1
на использование этой функции. Однако Old ksh не поддерживает$()
вPS1
. Так что, если это современная версия ksh, я хочуPS1
использовать созданную мной функцию; если это старая версия, я использую просто$PWD
.Ответы:
Я думаю, что
.sh.version
существует с первой версии ATT ksh 93. Он не доступен в pdksh или mksh. Так${.sh.version}
как это синтаксическая ошибка в оболочках, отличных от ksh93, оберните тест для него в подоболочку и защитите егоeval
.KSH_VERSION
начался в общедоступном клоне ksh (pdksh) и был добавлен в реальную оболочку Korn относительно недавно, в 2008 году, с помощью ksh93t.Вместо того, чтобы проверять номер версии, вы должны проверить конкретную функцию, которая вызывает у вас горе. Большинство функций можно проверить, попробовав некоторую конструкцию в подоболочке и посмотрев, не вызывает ли она ошибку.
источник
${.sh.version}
как синтаксическая ошибка, которая не может быть согласована. Я получаю сообщениеbad substitution
./dev/null
и игнорировать состояние выхода.eval '_sh_version=$(echo "${.sh.version}")' 2>/dev/null
лучше?KSH_VERSION
не был реализован вksh93
до версии 93t. Он будет установлен вmksh
,pdksh
,lksh
. Таким образом, для проверки версииksh
, мы можем попробовать эти шаги:KSH_VERSION
обнаружитьmksh
,pdksh
,lksh
ksh93
иksh88/86
( пусть Дэвид Корн покажет нам ).Имея это в виду, я пойду с:
источник
$KSH_VERSION
она не пуста? На моей машине с Ubuntu, это печатает "ksh93", покаKSH_VERSION
не установлено..kshrc
.ENV
переменная установлена (и обычно она установлена~/.kshrc
), скрипт обязательно прочитает.kshrc
файл. Конечно, для сценария было бы довольно странно устанавливать поддельное KSH_VERSION, но это, тем не менее, возможно, так же, как возможна ситуация, когда явно выполняется сценарий с интерпретатором, отличным от того, который указан в его первой строке.KSH_VERSION
. Иmksh
,pdksh
,lksh
,KSH_VERSION
помечается как неизменяемые.Для «настоящих»
ksh
выпусков (т.е. на основе AT & T) я использую эту команду:Вот различные выходные данные, которые я получаю:
Оригинал кш:
dtksh;
Современный кш93:
Для
pdksh
/msh
ksh
clones и современныхksh
версий AT & T , вот что работает:Редактировать:
Я упустил из виду, что вы спрашивали об этом внутри скрипта, а не зная путь к проверенному двоичному файлу ksh.
Предполагая, что вы действительно хотите использовать версию
ksh
, а не функции, которые она поддерживает, вот один из способов сделать это, используя толькоstrings
команду, которая должна работать, по крайней мере, в Linux и Solaris:Обратите внимание, что этот метод ненадежен, так как
/proc
может быть не смонтирован, и, безусловно, есть и другие недостатки Он не тестировался на других ОС Unix.источник
lksh
иpdksh
в Debian Джесси.lksh
иpdksh
не можешь разобраться со своимиKSH_VERSION
?strings
на них.KSH_VERSION
окончательно может.ksh
выпусков», я явно исключал не клоны AT & T, такие какpdksh
,mksh
иlksh
.strings
на некотором двоичном файле ksh - плохая идея, потому что вы не знаете, запускает ли он ваш скрипт. Может быть, ваш сценарий исполняется/usr/local/bin/ksh
или/home/bob/bin/ksh
или/bin/sh
или/usr/posix/bin/sh
или ...Когда я писал скрипт для
ksh
, я заметил, что-a
опция встроенной команды ksh,whence
похоже, не поддерживается в более старых версияхksh
. И это, похоже, верно для всех систем, которые я проверял, включая Solaris, AIX, HP-UX и Linux.Итак, вот решение в виде функции ksh:
И вот как это использовать:
источник
${.sh.version}
?whence
в Zsh есть-a
whence
команда, которая никоим образом не связана с ksh или ее версией. Я даже не знаю, почему вы захотите проверить, является ли ksh старой версией из экземпляра zsh, который представляет собой совершенно другую оболочку./bin/ksh
, например, на Debian Linux. Сейчас я не использую его там (и в настоящее время я не могу изменить свою регистрационную оболочку для проверки), поэтому я не знаю, читает ли она.kshrc
или нет, но я подозреваю, что это так.CTRL+ ALT+V
или
ESC, CTRL+V
Как правило, они оказались очень надежными в плане интерактивного определения версии KSH, которую вы используете, однако создание сценариев для них оказалось более сложным.
источник
set -o vi
чтобы установить сочетания клавиш как vi. До этого, или с + o vi или -o emacs, это просто не показывало бы мне. PD KSH v5.2.14 99/07 / 13.2 на openbsd 6.1Я думаю, что основная проблема с использованием $ {. Sh.version} заключается в том, что ksh88 просто останавливается с ненулевым кодом выхода.
Таким образом, мое решение состоит в том, чтобы поместить код, который ссылается на $ {. Sh.version}, в под-оболочку, а затем проверить, не завершен ли подоболочка и имеет ли код в под-оболочке, который будет работать на версиях ksh, где ссылка на $ {. sh.version} работает. Оборачивая его в функцию, которая затем вызывается другой функцией, которая переворачивает код возврата, так что последний вызов проверяет истинность.
Я запустил это в AIX и Oracle Enterprise Linux 5 & 6 с ksh88, ksh93 и pdksh.
Пит
источник
.sh.version
(действительноKSH_VERSION
, фактически псевдоним для этого). Также некоторые оболочки, например NetBSD sh, просто прекращают чтение после обнаружения,${.sh.version}
и никакое перенаправление не может заставить их запустить скрипт.Следующее, кажется, работает достаточно хорошо для всех протестированных мной оболочек, включая старый ksh88e и почти полный набор распространенных клонов Ksh (хотя только по одной версии каждого), хотя я еще не тестировал настоящую оригинальную оболочку Bourne ( и для этого может потребоваться адаптация
test
выражения для более старых версий ....Приложение:
Теперь я также успешно проверил это с помощью семейной реликвии Bourne Shell, хотя и с внешней (и более современной)
test
программой.источник
${.sh.version}
не могут быть частью решения, потому что определенные версии ksh - версии, о которых беспокоился исходный пост - фатально ошибаются в этом синтаксисе.