Comment surmonter une incompatibilité entre le ksh sous Linux et celui installé sous AIX / Solaris / HPUX?

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

  •  09-06-2019
  •  | 
  •  

Question

Je participe au processus de portage d'un système contenant plusieurs centaines de scripts ksh d'AIX, Solaris et HPUX vers Linux. Je suis tombé sur la différence suivante dans la manière dont ksh se comporte sur les deux systèmes:

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

Sous AIX, Solaris et HPUX, la sortie est "flag = true". sous Linux, la sortie est "flag = false".

Mes questions sont les suivantes:

  • Existe-t-il une variable d'environnement que je puisse définir pour que ksh de Linux se comporte comme le d'autres Os? En cas d'échec:
  • Existe-t-il une option sur ksh de Linux pour obtenir le comportement requis? En cas d'échec:
  • Une implémentation ksh est-elle disponible pour Linux avec le comportement souhaité?

Autres notes:

  • Sous AIX, Solaris et HPUX, ksh est une variante de ksh88.
  • Sous Linux, ksh est le domaine public ksh (pdksh)
  • Sous AIX, les dtksh et ksh93 (où je les ai installés) sous Solarux et HPUX sont compatibles avec ksh
  • Les systèmes Windows NT auxquels j'ai accès: Cygwin et MKS NT sont compatibles avec Linux.
  • Sous AIX, Solaris et Linux, bash est cohérent, donnant le résultat incorrect (de mon point de vue) de "flag = false".

Le tableau suivant récapitule les systèmes du problème:

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

Mettre à jour

Après quelques conseils de personnes de mon entreprise, nous avons décidé d’apporter la modification suivante au code. Cela nous donne le même résultat, que vous utilisiez le paramètre "réel" ou "réel". ksh (ksh88, ksh93) ou l'un des clones de ksh (pdksh, MSK ksh). Cela fonctionne également correctement avec bash.

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

Merci à jj33 pour la réponse précédemment acceptée.

Était-ce utile?

La solution 2

Après quelques conseils de personnes de mon entreprise, nous avons décidé d’apporter la modification suivante au code. Cela nous donne le même résultat, que vous utilisiez le paramètre "réel" ou "réel". ksh (ksh88, ksh93) ou l'un des clones de ksh (pdksh, MSK ksh). Cela fonctionne également correctement avec bash.

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

Merci à jj33 pour la réponse précédemment acceptée.

Autres conseils

Au lieu d'utiliser pdksh sur Linux, utilisez le paramètre "real". ksh de kornshell.org. pdksh est une ré-implémentation aveugle de ksh. kornshell.org est la coquille originale de Korn datant de 25 ans environ (celle écrite par David Korn). AIX et Solaris utilisent les versions du fichier ksh d'origine. La version de kornshell.org est donc généralement complète et compliquée. Après avoir fait mes armes sous SunOS / Solaris, installer kornshell.org ksh est généralement l’une des premières choses que je fais sur une nouvelle machine Linux ...

J'ai installé 'ksh' et 'pdksh' sur mon système 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 a le " correct " comportement que vous attendez alors que pdksh ne le fait pas. Vous pouvez vérifier le référentiel de logiciels de votre distribution Linux locale pour un "réel". ksh, au lieu d'utiliser pdksh. Le "Real Unix" Les systèmes d’exploitation vont installer la version AT & T de Korn shell, plutôt que pdksh, par défaut, car ils sont basés sur AT & T Unix (System V): -).

La différence s'explique par le fait que le bloc interne est exécuté dans le contexte du shell d'origine ou dans un sous-shell. Vous pourrez peut-être contrôler cela avec les commandes de regroupement () et {}. Utiliser un fichier temporaire, comme vous le faites dans votre mise à jour, fonctionnera la plupart du temps, mais rencontrera des problèmes si le script est exécuté deux fois rapidement, ou s'il s'exécute sans effacer le fichier, etc.

.

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

Cela peut aider à résoudre le problème rencontré sur le ksh Linux. Si vous utilisez des parenthèses au lieu d'accolades, vous obtiendrez le comportement Linux sur les autres implémentations de ksh.

Voici une autre solution pour écho "\ n". problème

Étapes:

  1. Rechercher le nom du package ksh

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

  1. désinstaller ksh $ sudo yum remove ksh-20100621-19.el6_4.3.x86_64

  2. chargez pdksh-5.2.14-37.el5_8.1.x86_64.rpm (vérifiez le système d'exploitation pour les versions 32 bits ou 64 bits et choisissez le paquet correct)

  3. Installez 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

Sortie avant l'installation 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

Après l'installation de PDKSH

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

Utilisation: START

./ ora_db_start_stop.sh START ALL

OU

./ ora_db_start_stop.sh START ONE_OR_MORE

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

Utilisation: STOP

./ ora_db_start_stop.sh ARRETER TOUT

OU

./ ora_db_start_stop.sh STOP ONE_OR_MORE

Je ne connais aucune option particulière pour forcer ksh à être compatible avec une version plus ancienne. Cela dit, vous pourriez peut-être installer une très ancienne version de ksh sur votre machine Linux et la faire se comporter de manière compatible?

Il serait peut-être plus facile d'installer une version plus moderne d'amy shell sur les boîtes AIX / HP-UX et de migrer vos scripts pour qu'ils utilisent sh. Je sais qu'il existe des versions de bash disponibles pour toutes les plateformes.

Votre script donne le résultat correct (vrai) lorsque zsh est utilisé avec l'option emulate -L ksh . Si tout échoue, vous pouvez utiliser zsh sous Linux.

Devez-vous rester dans ksh?

Même si vous utilisez le même ksh, vous continuerez à appeler toutes sortes de commandes externes (grep, ps, cat, etc ...) dont certaines parties auront des paramètres différents et une sortie différente d’un système à l’autre. Soit vous devez tenir compte de ces différences, soit utiliser la version GNU de chacune d’elles pour rendre les choses identiques.

Le langage de programmation Perl a été conçu à l'origine pour résoudre ce problème. Il comprend toutes les fonctionnalités qu'un programmeur shell Unix voudrait du programme shell mais c'est la même chose sur tous les systèmes Unix. Vous pourriez ne pas avoir la dernière version sur tous ceux systèmes, mais si vous avez besoin d’installer quelque chose, il vaut peut-être mieux installer perl.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top