¿Cómo puedo obtener la versión de ksh de forma segura desde un script ksh?
He visto las siguientes soluciones :
ksh --versionecho ${.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},kshtrata 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 substitutionPor supuesto,
echo $KSH_VERSIONparece funcionar bien, quiero decir que no se bloqueará, aunque en estas máquinas está en blanco. Además, vi en algún lugar queKSH_VERSIONse establece solo porpdksh.
Preguntas:
- ¿Cómo puedo verificar la versión de forma segura mediante
kshprogramació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_VERSIONlo suficientemente bueno? Quiero decir, si está en blanco, ¿eskshnecesariamente 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

PS1para usar esta función. Sin embargo, Old ksh no es compatible$()conPS1. Entonces, si es una versión moderna de ksh, quieroPS1usar la función que creé; si es la versión anterior, yo solo uso$PWD.Respuestas:
Creo que
.sh.versionha 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_VERSIONcomenzó 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/nulle ignorar el estado de salida.eval '_sh_version=$(echo "${.sh.version}")' 2>/dev/nullFunciona mejor?KSH_VERSIONno se implementóksh93antes de la versión 93t. Se encuentra enmksh,pdksh,lksh. Entonces, para verificar la versión deksh, podemos probar estos pasos:KSH_VERSIONde detectarmksh,pdksh,lkshksh93yksh88/86( deje que David Korn nos lo muestre ).Con esto en mente, iré con:
fuente
$KSH_VERSIONno está en blanco primero? En mi máquina Ubuntu, esto imprime "ksh93", peroKSH_VERSIONestá configurado..kshrc.ENVvariable está configurada (y normalmente está configurada en~/.kshrc), el script definitivamente leerá el.kshrcarchivo. 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_VERSIONse marca como de sólo lectura.Para las
kshversiones "reales" (es decir, basadas en AT&T), utilizo este comando:Aquí hay varios resultados que obtengo:
Ksh original:
dtksh;
Ksh93 moderno:
Para
pdksh/mshkshclones ykshversiones 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
kshutilizado, y no las características que admite, aquí hay una forma de hacerlo utilizando solo elstringscomando que debería funcionar al menos en Linux y Solaris:Tenga en cuenta que este método no es confiable ya que
/procpodría no estar montado, y ciertamente hay otras debilidades. No se ha probado en otros sistemas operativos Unix.fuente
lkshypdkshen Debian Jessie.lkshypdkshno se puede separar de ellosKSH_VERSION?stringssobre ellos.KSH_VERSIONdefinitivamente puede.kshlanzamientos " reales " , estaba excluyendo explícitamente los clones ksh que no son de AT&T comopdksh,mkshylksh.stringsen 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/ksho/home/bob/bin/ksho/bin/sho/usr/posix/bin/sho ...Mientras escribía un script para
ksh, noté que la-aopción delwhencecomando 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}?whenceen Zsh tiene-awhencecomando 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.kshrco 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 viObtuve 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_VERSIONes 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
testexpresió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.