Wie eine Inkompatibilität zwischen dem KSH auf Linux vs. zu überwinden, die auf AIX / Solaris / HP-UX installiert?

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

  •  09-06-2019
  •  | 
  •  

Frage

Ich bin involviert in den Prozess ein System der Portierung von mehreren hundert ksh-Skripte von AIX, Solaris und HP-UX auf Linux enthält. Ich habe über den folgenden Unterschied kam in der Art und Weise KSH auf den beiden Systemen verhält:

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

Unter AIX, Solaris und HP-UX ist der Ausgang "Flag = true" auf Linux ist der Ausgang "Flag = false".

Meine Fragen sind:

  • Gibt es eine Umgebungsvariable, die ich setzen kann Linux KSH zu verhalten wie die bekommen andere Os des? Gelingt das nicht:
  • Gibt es eine Option auf Linux KSH das erforderliche Verhalten zu bekommen? Gelingt das nicht:
  • Sie hat eine KSH Implementierung für Linux mit dem gewünschten Verhalten?

Andere Anmerkungen:

  • Unter AIX, Solaris und HP-UX KSH ist eine Variante des ksh88.
  • Unter Linux KSH ist die Public Domain KSH (pdksh)
  • Unter AIX, Solaris und HP-UX dtksh und ksh93 (wo ich sie installiert haben) mit KSH konsistent sind
  • Die Windows NT-Systemen I haben Zugriff zu: Cygwin und MKS NT, stehen im Einklang mit Linux
  • .
  • Unter AIX, Solaris und Linux, bash konsistent ist, die falsche Angabe (aus meiner Sicht) Ergebnis der "Flag = false".

Die folgende Tabelle fasst die Systeme das Problem:

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

Update

Nach einiger Beratung von Menschen in meinem Unternehmen haben wir beschlossen, die folgende Änderung an den Code zu machen. Dies gibt uns das gleiche Ergebnis, ob die „echte“ kshs mit (ksh88, ksh93) oder einen der KSH Klone (pdksh, MSK KSH). Dies funktioniert auch korrekt mit bash.

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

Dank jj33 für die zuvor akzeptierte Antwort.

War es hilfreich?

Lösung 2

Nach einiger Beratung von Menschen in meinem Unternehmen haben wir beschlossen, die folgende Änderung an den Code zu machen. Dies gibt uns das gleiche Ergebnis, ob die „echte“ kshs mit (ksh88, ksh93) oder einen der KSH Klone (pdksh, MSK KSH). Dies funktioniert auch korrekt mit bash.

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

Danke für die vorherige akzeptierte Antwort auf jj33.

Andere Tipps

Statt pdksh auf Linux, verwenden Sie die "echte" ksh von kornshell.org zu verwenden. pdksh ist eine blinde Neuimplementierung von KSH. kornshell.org ist die ursprüngliche Datierung Korn-Shell 25 Jahre zurück oder so (die von David Korn geschrieben eins). AIX und Solaris verwenden Versionen des ursprünglichen KSH, so dass die kornshell.org Version ist in der Regel Feature- und Bug- abgeschlossen. Nachdem ich meine Zähne mit SunOS / Solaris geschnitten, Installation kornshell.org KSH in der Regel eines der ersten Dinge, die ich auf eine neue Linux-Box zu tun ...

Ich installierte 'KSH' und 'pdksh' auf meinem lokalen Ubuntu Hardy System.

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 hat das „richtige“ Verhalten, das Sie erwarten, während pdksh nicht. Sie können Ihre lokale Software-Repository für einen „echten“ ksh der Linux-Distribution überprüfen, statt pdksh zu verwenden. Die "echte Unix" OS werden die AT & T-Version von Korn-Shell, anstatt pdksh, die standardmäßig installiert werden, was mit ihnen basiert weg ist AT & T Unix (System V): -).

Der Grund für die Unterschiede ist, ob der innere Block in dem ursprünglichen Shell-Kontext oder in einer Subshell ausgeführt wird. Sie können dies steuern können mit dem () und {} Gruppierung Befehle. Unter Verwendung einer temporären Datei, wie Sie in Ihrem Update tun, wird die meiste Zeit arbeiten, aber auf Probleme stoßen, wenn das Skript zweimal schnell ausgeführt wird, oder wenn er ausgeführt wird, ohne die Datei zu löschen, etc.

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

Das kann mit dem Problem helfen Sie auf dem Linux-KSH bekommen wurden. Wenn Sie Klammern statt Klammern verwenden, werden Sie das Linux-Verhalten auf den anderen KSH-Implementierungen erhalten.

Hier ist die andere Lösung für echo "\ n" Ausgabe

Schritte:

  1. Finden KSH Paketnamen

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

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

  2. down load pdksh-5.2.14-37.el5_8.1.x86_64.rpm (Bitte überprüfen OS für 32-Bit- oder 64-Bit und korrekte Pkg wählen)

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

Ausgabe vor pdksh installieren

$ 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

Nach pdksh installieren

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

Verbrauch: START

./ora_db_start_stop.sh START ALL

oder

./ora_db_start_stop.sh START ONE_OR_MORE

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

Usage: STOP

./ora_db_start_stop.sh STOP ALL

oder

./ora_db_start_stop.sh STOP ONE_OR_MORE

Ich weiß nicht, von einer bestimmten Option KSH zu zwingen, mit einer bestimmten älteren Version kompatibel zu sein. Das heißt, vielleicht Sie eine sehr alte Version des KSH auf Ihrem Linux-System installieren zu können, und haben es in einem kompatiblen Weise verhalten?

Es könnte einfacher sein, eine modernere Version von amy Shell auf der AIX / HP-UX-Boxen zu installieren und einfach Ihre Skripte migrieren sh zu verwenden. Ich weiß, es gibt Versionen von bash für alle Plattformen.

Das Skript gibt die richtige (true) ausgegeben wird, wenn zsh mit der emulate -L ksh Option verwendet wird. Wenn alle Stricke reißen möchten Sie vielleicht mit zsh auf Linux versuchen.

Haben Sie innerhalb KSH bleiben müssen?

Auch wenn Sie die gleiche ksh verwenden Sie werden immer noch alle Arten von externen Kommandos aufrufen (grep, ps, Katze, etc ...) Teil von ihnen werden verschiedene Parameter und unterschiedlichen Ausgabe von System zu System. Entweder Sie werden diese Unterschiede in Rechnung zu tragen haben oder die GNU-Version von jedem von ihnen verwenden, um die Dinge gleich.

Die Perl Programmiersprache wurde ursprünglich entwickelt, um genau dieses Problem zu überwinden. Es beinhaltet alle Funktionen, die ein Unix-Shell-Programmierer wollen würde von ihm Programm Shell aber es ist das gleiche auf jedem Unix-System. Sie werden vielleicht nicht die neueste Version auf alle, Systeme, aber wenn Sie etwas installieren müssen, vielleicht ist es besser, Perl zu installieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top