¿Cómo puedo obtener la versión de ksh de forma segura desde un script ksh?
He visto las siguientes soluciones :
ksh --version
echo ${.sh.version}
echo $KSH_VERSION
Y dadas las circunstancias correctas, cada uno de estos funciona correctamente. Sin embargo, me importa el caso no perfecto.
Específicamente, hay varias máquinas con las que trabajo que tienen versiones anteriores de ksh que, para mis propósitos, carecen de funcionalidad. De todos modos, la razón por la que quiero verificar la versión (programáticamente) es para ver si la versión ksh es una de las versiones menos capaces; y si es así, quiero ejecutar una rama con un código menos sorprendente.
Sin embargo, en las máquinas problemáticas, la ineptitud del shell se extiende hasta verificar la versión ...
- Si lo intento
ksh --version
, no imprime nada y abre una nueva instancia deksh
! Si lo intento
echo ${.sh.version}
,ksh
trata esto como un error de sintaxis con el que no se puede descartar2> /dev/null
.$ echo ${.sh.version} 2> /dev/null ksh: ${.sh.version}: bad substitution
Por supuesto,
echo $KSH_VERSION
parece funcionar bien, quiero decir que no se bloqueará, aunque en estas máquinas está en blanco. Además, vi en algún lugar queKSH_VERSION
se establece solo porpdksh
.
Preguntas:
- ¿Cómo puedo verificar la versión de forma segura mediante
ksh
programación? Para mis propósitos aquí, realmente no me importa cuál es el número de versión real, solo si es una versión desactualizadaksh
. - Es
$KSH_VERSION
lo suficientemente bueno? Quiero decir, si está en blanco, ¿esksh
necesariamente una versión desactualizada? ¿Era correcto ese otro foro en el que podría no estar configurado incluso para versiones más recientesksh
? - ¿No hay forma de verificar esto?
fuente
PS1
para usar esta función. Sin embargo, Old ksh no es compatible$()
conPS1
. Entonces, si es una versión moderna de ksh, quieroPS1
usar la función que creé; si es la versión anterior, yo solo uso$PWD
.Respuestas:
Creo que
.sh.version
ha existido desde la primera versión de ATT ksh 93. No está disponible en pdksh o mksh. Como se${.sh.version}
trata de un error de sintaxis en shells distintos de ksh93, envuelva la prueba en un subshell y protéjalo detráseval
.KSH_VERSION
comenzó en el dominio público ksh clone (pdksh), y se agregó al shell Korn real hace relativamente poco, en 2008 con ksh93t.En lugar de probar un número de versión, debe probar la función específica que le causa dolor. La mayoría de las características se pueden probar probando alguna construcción en una subshell y ver si desencadena un error.
fuente
${.sh.version}
como un error de sintaxis que no se puede conciliar. El mensaje que recibo esbad substitution
./dev/null
e ignorar el estado de salida.eval '_sh_version=$(echo "${.sh.version}")' 2>/dev/null
Funciona mejor?KSH_VERSION
no se implementóksh93
antes de la versión 93t. Se encuentra enmksh
,pdksh
,lksh
. Entonces, para verificar la versión deksh
, podemos probar estos pasos:KSH_VERSION
de detectarmksh
,pdksh
,lksh
ksh93
yksh88/86
( deje que David Korn nos lo muestre ).Con esto en mente, iré con:
fuente
$KSH_VERSION
no está en blanco primero? En mi máquina Ubuntu, esto imprime "ksh93", peroKSH_VERSION
está configurado..kshrc
.ENV
variable está configurada (y normalmente está configurada en~/.kshrc
), el script definitivamente leerá el.kshrc
archivo. Por supuesto, sería bastante extraño que un script establezca una KSH_VERSION falsa, pero sin embargo esto es posible, al igual que ejecutar explícitamente un script con un intérprete diferente al especificado en su primera línea es una situación posible.KSH_VERSION
. Y enmksh
,pdksh
,lksh
,KSH_VERSION
se marca como de sólo lectura.Para las
ksh
versiones "reales" (es decir, basadas en AT&T), utilizo este comando:Aquí hay varios resultados que obtengo:
Ksh original:
dtksh;
Ksh93 moderno:
Para
pdksh
/msh
ksh
clones yksh
versiones modernas de AT&T también, aquí hay algo que funciona:Editar:
Pasé por alto que estabas preguntando acerca de hacerlo desde dentro de un script, no sabiendo la ruta al binario ksh probado.
Suponiendo que realmente desea la versión de
ksh
utilizado, y no las características que admite, aquí hay una forma de hacerlo utilizando solo elstrings
comando que debería funcionar al menos en Linux y Solaris:Tenga en cuenta que este método no es confiable ya que
/proc
podría no estar montado, y ciertamente hay otras debilidades. No se ha probado en otros sistemas operativos Unix.fuente
lksh
ypdksh
en Debian Jessie.lksh
ypdksh
no se puede separar de ellosKSH_VERSION
?strings
sobre ellos.KSH_VERSION
definitivamente puede.ksh
lanzamientos " reales " , estaba excluyendo explícitamente los clones ksh que no son de AT&T comopdksh
,mksh
ylksh
.strings
en algún binario de ksh es una mala idea porque no sabes si ese es el que ejecuta tu script. Tal vez tu guión esté siendo ejecutado por/usr/local/bin/ksh
o/home/bob/bin/ksh
o/bin/sh
o/usr/posix/bin/sh
o ...Mientras escribía un script para
ksh
, noté que la-a
opción delwhence
comando incorporado de ksh parece no ser compatible con versiones anteriores deksh
. Y esto parece ser cierto en todos los sistemas que verifiqué, incluidos Solaris, AIX, HP-UX y Linux.Así que aquí está la solución como una función ksh:
Y aquí está cómo usarlo:
fuente
${.sh.version}
?whence
en Zsh tiene-a
whence
comando incorporado que de ninguna manera está vinculado a ksh o la versión del mismo. Ni siquiera sé por qué querrías comprobar si ksh es una versión antigua desde una instancia de zsh, que es un shell completamente diferente./bin/ksh
, por ejemplo, en Debian Linux. Ahora no lo uso allí (y por el momento no puedo cambiar mi shell de inicio de sesión para verificar), así que no sé si se lee.kshrc
o no, pero sospecharía que sí.CTRL+ ALT+V
o
ESC, CTRL+V
Por lo general, han demostrado ser muy confiables en lo que respecta a la determinación interactiva de la versión de KSH que está utilizando, sin embargo, crear scripts es más difícil.
fuente
set -o vi
Obtuve la opción <kbd> ESC </kbd>, <kbd> CTRL </kbd> + <kbd> V </kbd> para trabajar, después de ejecutar para configurar las combinaciones de teclas para que sean como vi. Antes de eso, o con + o vi o -o emacs, simplemente no me mostraría. PD KSH v5.2.14 99/07 / 13.2 en openbsd 6.1Creo que el problema fundamental con el uso de $ {. Sh.version} es que ksh88 simplemente se detiene, con un código de salida distinto de cero.
Por lo tanto, mi solución es poner el código que hace referencia a $ {. Sh.version} en un sub-shell, luego probar para ver si el sub-shell sale de cero y tiene un código en el sub-shell que funcionará en versiones de el ksh donde hacer referencia a $ {. sh.version} funciona. Envolviéndolo en una función que luego es llamada por otra función que invierte el código de retorno, de modo que la última llamada verifica que sea verdadera.
He ejecutado esto en AIX y Oracle Enterprise Linux 5 y 6, con ksh88, ksh93 y pdksh.
Pete
fuente
.sh.version
(de hechoKSH_VERSION
es un alias para ello). También algunos shells, por ejemplo, NetBSD sh, simplemente dejan de leer después de encontrarse${.sh.version}
y ninguna cantidad de redirección puede mantenerlos ejecutando el script.Lo siguiente parece funcionar razonablemente bien para todos los shells que he probado, incluido el viejo ksh88e y una gama casi completa de clones Ksh comunes (aunque solo una versión de cada uno), aunque todavía no he probado un shell Bourne original real ( y hacerlo puede requerir adaptar la
test
expresión para versiones anteriores ...Apéndice:
Ahora también he probado con éxito esto con Heirloom Bourne Shell, aunque con un programa externo (y más moderno)
test
.fuente
${.sh.version}
no pueden ser parte de la solución porque ciertas versiones de ksh, las versiones que preocupaban a la publicación original, tienen un error fatal en esa sintaxis.