Wie eine Inkompatibilität zwischen dem KSH auf Linux vs. zu überwinden, die auf AIX / Solaris / HP-UX installiert?
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.
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:
- Finden KSH Paketnamen
$ rpm -qa --queryformat "%{NAME}-%{VERSION}-%{RELEASE}(%{ARCH})\n" | grep "ksh"
ksh-20100621-19.el6_4.3(x86_64)
-
uninstall KSH
$ sudo yum remove ksh-20100621-19.el6_4.3.x86_64
-
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)
-
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.