Cómo superar una incompatibilidad entre ksh en Linux vs.que está instalado en AIX/Solaris/HPUX?

StackOverflow https://stackoverflow.com/questions/74372

  •  09-06-2019
  •  | 
  •  

Pregunta

Estoy involucrado en el proceso de portar un sistema que contiene varios cientos de scripts ksh de AIX, Solaris y HPUX a Linux.Me he encontrado con la siguiente diferencia en la forma en que se comporta ksh en los dos sistemas:

#!/bin/ksh
flag=false
echo "a\nb" | while read x
do
    flag=true
done
echo "flag = ${flag}"
exit 0

En AIX, Solaris y HPUX, la salida es "flag = true" y en Linux, la salida es "flag = false".

Mis preguntas son:

  • ¿Hay una variable de entorno que pueda configurar para que el KSH de Linux se comporte como el otro sistema operativo '?Fallando en eso:
  • ¿Existe una opción en ksh de Linux para obtener el comportamiento requerido?Fallando en eso:
  • ¿Existe una implementación de ksh disponible para Linux con el comportamiento deseado?

Otras notas:

  • En AIX, Solaris y HPUX, ksh es una variante de ksh88.
  • En Linux, ksh es el dominio público ksh (pdksh)
  • En AIX, Solaris y HPUX dtksh y ksh93 (donde los tengo instalados) son consistentes con ksh
  • Los sistemas Windows NT a los que tengo acceso:Cygwin y MKS NT son consistentes con Linux.
  • En AIX, Solaris y Linux, bash es consistente y da el resultado incorrecto (desde mi perspectiva) de "flag = false".

La siguiente tabla resume los sistemas que tienen el problema:

uname -s       uname -r                   which ksh          ksh version                     flag =
========       ========                   =========          ===========                     ======
Linux          2.6.9-55.0.0.0.2.ELsmp     /bin/ksh           PD KSH v5.2.14 99/07/13.2       false
AIX            3                          /bin/ksh           Version M-11/16/88f             true    // AIX 5.3
                                          /bin/ksh93         Version M-12/28/93e             true
SunOS          5.8, 5.9 and 5.10          /bin/ksh           Version M-11/16/88i             true
                                          /usr/dt/bin/dtksh  Version M-12/28/93d             true
HP-UX          B.11.11 and B.11.23        /bin/ksh           Version 11/16/88                true
                                          /usr/dt/bin/dtksh  Version M-12/28/93d             true
CYGWIN_NT-5.1  1.5.25(0.156/4/2)          /bin/ksh           PD KSH v5.2.14 99/07/13.2       false
Windows_NT     5                          .../mksnt/ksh.exe  Version 8.7.0 build 1859...     false    // MKS

Actualizar

Después de algunos consejos de personas de mi empresa, decidimos realizar la siguiente modificación al código.Esto nos da el mismo resultado ya sea que usemos los ksh "reales" (ksh88, ksh93) o cualquiera de los clones de ksh (pdksh, MSK ksh).Esto también funciona correctamente con bash.

#!/bin/ksh
echo "a\nb" > junk
flag=false
while read x
do
    flag=true
done < junk
echo "flag = ${flag}"
exit 0

Gracias a jj33 por la respuesta previamente aceptada.

¿Fue útil?

Solución 2

Después de algunos consejos de personas de mi empresa, decidimos realizar la siguiente modificación al código.Esto nos da el mismo resultado ya sea que usemos los ksh "reales" (ksh88, ksh93) o cualquiera de los clones de ksh (pdksh, MSK ksh).Esto también funciona correctamente con bash.

#!/bin/ksh
echo "a\nb" > junk
flag=false
while read x
do
    flag=true
done < junk
echo "flag = ${flag}"
exit 0

Gracias a jj33 por la respuesta aceptada anteriormente.

Otros consejos

En lugar de usar pdksh en Linux, use el ksh "real" de kornshell.org.pdksh es una reimplementación ciega de ksh.kornshell.org es el shell de korn original que data de hace aproximadamente 25 años (el escrito por David Korn).AIX y Solaris utilizan versiones del ksh original, por lo que la versión de kornshell.org suele estar completa en cuanto a características y errores.Después de haberme iniciado con SunOS/Solaris, instalar kornshell.org ksh suele ser una de las primeras cosas que hago en una nueva máquina Linux...

Instalé 'ksh' y 'pdksh' en mi sistema Ubuntu Hardy local.

ii  ksh            93s+20071105-1 The real, AT&T version of the Korn shell
ii  pdksh          5.2.14-21ubunt A public domain version of the Korn shell

ksh tiene el comportamiento "correcto" que espera, mientras que pdksh no.Puede buscar en el repositorio de software de su distribución local de Linux un ksh "real", en lugar de utilizar pdksh.Los sistemas operativos "Real Unix" instalarán la versión AT&T del shell Korn, en lugar de pdksh, de forma predeterminada, ya que están basados ​​en AT&T Unix (System V) :-).

El motivo de las diferencias es si el bloque interno se ejecuta en el contexto del shell original o en un subshell.Es posible que pueda controlar esto con los comandos de agrupación () y {}.El uso de un archivo temporal, como lo hace en su actualización, funcionará la mayor parte del tiempo, pero generará problemas si el script se ejecuta dos veces rápidamente o si se ejecuta sin borrar el archivo, etc.

#!/bin/ksh
flag=false
echo "a\nb" | { while read x
do    
     flag=true
done }
echo "flag = ${flag}"
exit 0

Eso puede ayudar con el problema que tenía en Linux ksh.Si usa paréntesis en lugar de llaves, obtendrá el comportamiento de Linux en las otras implementaciones de ksh.

Aquí está otra solución para el problema del eco " "

Pasos:

  1. Encuentra el nombre del paquete ksh

$ rpm -qa --queryformat "%{NAME}-%{VERSION}-%{RELEASE}(%{ARCH})\n" | grep "ksh" ksh-20100621-19.el6_4.3(x86_64)

  1. desinstalar ksh$ sudo yum remove ksh-20100621-19.el6_4.3.x86_64

  2. descargue pdksh-5.2.14-37.el5_8.1.x86_64.rpm (verifique el sistema operativo para 32 o 64 bits y elija el paquete correcto)

  3. Instalar pdksh-5.2.14-37.el5_8.1.x86_64.rpm

$ sudo yum -y install /SCRIPT_PATH/pdksh-5.2.14-37.el5_8.1.x86_64.rpm

Salida antes de la instalación de PDKSH

$ ora_db_start_stop.sh
\n==============
Usage: START
==============\n\n
./ora_db_start_stop.sh START ALL    \n
OR \n
./ora_db_start_stop.sh START ONE_OR_MORE    \n
\n==============
Usage: STOP
==============\n\n
./ora_db_start_stop.sh STOP ALL    \n
OR \n
./ora_db_start_stop.sh STOP ONE_OR_MORE    \n\n

Después de la instalación de PDKSH

==============

Uso:COMENZAR

./ora_db_start_stop.sh START ALL

O

./ora_db_start_stop.sh START ONE_OR_MORE

==============

Uso:DETENER

./ora_db_start_stop.sh STOP ALL

O

./ora_db_start_stop.sh STOP ONE_OR_MORE

No conozco ninguna opción particular para obligar a ksh a ser compatible con una versión anterior en particular.Dicho esto, ¿quizás podrías instalar una versión muy antigua de ksh en tu máquina Linux y hacer que se comporte de manera compatible?

Podría ser más fácil instalar una versión más moderna de amy shell en las cajas AIX/HP-UX y simplemente migrar sus scripts para usar sh.Sé que hay versiones de bash disponibles para todas las plataformas.

Su secuencia de comandos proporciona la salida correcta (verdadera) cuando zsh se utiliza con el emulate -L ksh opción.Si todo lo demás falla, es posible que desees intentar usar zsh en Linux.

¿Tienes que permanecer dentro de ksh?

Incluso si usa el mismo ksh, seguirá llamando a todo tipo de comandos externos (grep, ps, cat, etc.) algunos de ellos tendrán diferentes parámetros y diferentes resultados de un sistema a otro.O tendrás que tener en cuenta esas diferencias o usar la versión GNU de cada una de ellas para que todo sea igual.

El perla El lenguaje de programación originalmente fue diseñado exactamente para superar este problema.Incluye todas las características que un programador de shell Unix desearía del programa HE Shell, pero es lo mismo en cada sistema UNIX.Es posible que no tenga la última versión en todos esos sistemas, pero si necesita instalar algo, tal vez sea mejor instalar Perl.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top