Discussion:
Unterschied print/read -p unter Solaris ksh88 vs Linux ksh93
(zu alt für eine Antwort)
Celal Dikici
2019-12-11 19:50:00 UTC
Permalink
Hallo Community,

ich portiere gerade einige ksh-Scripte aus einer Solaris 5.10 Installation (ksh-Version M-11/16/88i) nach RedHat 7.x Linux (ksh-Version AJM 93u+ 2012-08-01).

Dabei habe ich Schwierigkeiten mit Co-Prozessen und Kommunikation mit denen.

Der Script LimExport.sh sieht dabei vereinfacht so aus:

[Code]
#!/bin/ksh

function admin_subprocs
{
integer num
while read num; do
(($num)) && echo $num || break
done
}

...cut...

# interne Hilfsvariablen deklarieren
integer -r limex_parallel=3
typeset limitname
integer limittype limexnum=0 limexcount=0

function do_limexport {
integer mynum=$1
typeset limit=$2
melde INFO "$MYNAME: Der limexport-Unterprozess Nr. $mynum verarbeitet '$limit'"
limexport "${DATABASE}" -c "$cfgfile" >>"$datfile" 2>>"$LOGFILE" && print -p $mynum || print -p 0 &
return 0
} # END func

melde INFO "$MYNAME: Die Limite aus der Konfig '$CONFIG' werden in $limex_parallel limexport-Unterprozessen verarbeitet"
# Co-Prozess zur Verwaltung der Paralleljobs starten und Löschroutine (trap) bei Beendigung deklarieren
admin_subprocs |&
trap "pkill -P $$; rm -rf $limdir" EXIT


# LimitTypes auslesen und parallel verarbeiten
GetMultiConfig | while read limitname limittype; do
if (($limexcount < $limex_parallel)); then
limexnum=$((limexcount += 1))
else
if ! read -p limexnum; then # freie Prozessnummer aus Co-Prozess lesen
melde FEHLER "$MYNAME: Fehler während der Verarbeitung eines limexport-Unterprozesses! Abbruch."
exit 1
fi
fi
do_limexport $limexnum "$limitname,$limittype" # LimitExport-Funktion aufrufen
done

# Auf Unterprozesse warten, indem der Co-Prozess ausgelesen wird
while (($limexcount > 0)); do
read -p limexnum
melde INFO "$MYNAME: Der limexport-Unterprozess Nr. $limexnum ist fertig."
((limexcount -= 1))
done
print -p 0 # Terminierung an Co-Prozess schicken

# Limit-Export-Ausgaben der einzelnen Prozesse zusammenfassen
melde INFO "$MYNAME: Die Ergebnisse der limexport-Unterprozesse werden zur BCP-Datei '$BCPOUTFILE' zusammengefasst"
createBCPFile *.dat
exit 0
[/Code]


Wenn ich nun Script laufen lasse, werden zwar durch die binary limexport die "$datfile" Dateien (3 Stück, wie in $limex_parallel definiert) erzeugt, jedoch bekomme ich folgenden Fehler:

...cut...
+ limexnum=3
+ do_limexport 3 GARANT,1
INFO 11.12.2019 19:45:19: limexport: Der limexport-Unterprozess Nr. 3 verarbeitet Limit 'GARANT,1'
+ ((3 < 3))
+ read -p limexnum

/opt/L/bin/LimExport.sh[42]: do_limexport[22]: print: no query process [Bad file descriptor]
/opt/L/bin/LimExport.sh[42]: do_limexport[22]: print: no query process [Bad file descriptor]


...und der Script steht, bis man es mit Ctrl-C abbricht.


Ich habe vieles probiert aber so richtig komme ich nicht weiter.

Wenn ich die Parallelität erhöhe (auf z.B. 40 -soviele Dateien sind aktuell zu verarbeiten-), dann werden zwar alle benötigten *.dat Files erzeugt, aber da der Script nicht zum Ende kommt, können andere Programme nicht gestartet werden.

Wenn ich die read -p & print -p auskommentiere, kommt der Script zwar zum Ende, erzeugt jedoch nur 0 Byte *.dat Files.

Auch im Internet bin ich nicht wirklich weiter. Ein Unix.Stackexchange Artikel geht in die Richtung, jedoch hat die Lösung dort mich nicht weiter gebracht :(


Das ist nicht der einzige Script, der mit Co-Prozessen arbeitet. Daher ist es mir wichtig zu verstehen, warum das ksh-Script unter Linux nicht das gleiche Verhalten zeigt, wie auf Solaris (bzw. ksh88 vs ksh93).

Es ist OK, wenn sie unterschiedliches Verhalten zeigen; ich möchte es jedoch anhand des obigen Beispiels verstehen.


Vielen Dank für eure Tipps,
Celal
J***@fokus.fraunhofer.de
2019-12-12 12:30:14 UTC
Permalink
Post by Celal Dikici
Das ist nicht der einzige Script, der mit Co-Prozessen arbeitet. Daher ist es mir wichtig zu verstehen, warum das ksh-Script
unter Linux nicht das gleiche Verhalten zeigt, wie auf Solaris (bzw. ksh88 vs ksh93).
Was für ein ksh ist das denn auf Linux?

Ist das vielleicht der ksh93, der von Redhat Leuten "gepflegt" wird?
Die haben mangels Verständnis der Quellen schon viel zerstört.
--
EMail:***@schily.net (home) Jörg Schilling D-13353 Berlin
***@fokus.fraunhofer.de (work) Blog: http://schily.blogspot.com/
URL: http://cdrecord.org/private/ http://sourceforge.net/projects/schilytools/files/
Celal Dikici
2019-12-14 21:39:34 UTC
Permalink
In article <d6b55c2c-cc10-4ed3-b6bb-1b065b89620a,
Post by Celal Dikici
Das ist nicht der einzige Script, der mit Co-Prozessen arbeitet. Daher ist es mir wichtig zu verstehen, warum das ksh-Script
unter Linux nicht das gleiche Verhalten zeigt, wie auf Solaris (bzw. ksh88 vs ksh93).
Was für ein ksh ist das denn auf Linux?
Ist das vielleicht der ksh93, der von Redhat Leuten "gepflegt" wird?
Die haben mangels Verständnis der Quellen schon viel zerstört.
ja, das glaube ich schon (93u+ 2012-08-01), denn wo der RedHat installiert wurde, sind die sehr konservativ (Bank). Installieren also nur das, was in den offiziellen Repos vorhanden ist. Ich habe via Kornshell.org auch eine Aktualisierung von 2014 gefunden, wo das Problem gelöst worden sein soll, aber da das nicht offiz.Repo ist, gestaltet sich die Installation sehr schwierig.

Andererseits habe ich den Script auf meinem Mac mit

Celals-iMac:Development Celal$ ksh --version
version sh (AT&T Research) 93u+ 2012-08-01

getestet und bekomme den gleichen Fehler wir auf Linux.

Grüße,
Celal
Celal Dikici
2019-12-14 21:45:12 UTC
Permalink
Am Mittwoch, 11. Dezember 2019 20:50:01 UTC+1 schrieb Celal Dikici:
...
Post by Celal Dikici
Das ist nicht der einzige Script, der mit Co-Prozessen arbeitet. Daher ist es mir wichtig zu verstehen, warum das ksh-Script unter Linux nicht das gleiche Verhalten zeigt, wie auf Solaris (bzw. ksh88 vs ksh93).
Es ist OK, wenn sie unterschiedliches Verhalten zeigen; ich möchte es jedoch anhand des obigen Beispiels verstehen.
hat jemand einen Tipp. Auf meinem Mac mit

Celals-iMac:Development Celal$ ksh --version
version sh (AT&T Research) 93u+ 2012-08-01

bekomme ich die gleiche Fehlermeldung.

Ist es evtl. eine Idee, das mit Named Pipes zu realisieren? Ich probiere das aktuell, bin jedoch noch nicht weitergekommen.


hier ist ein komplettes Shellscript Beispiel, das man nehmen und verändern kann. Sie läuft unter Solaris 10
BlindesHuhn.sh

#!/bin/ksh

# XXX
# XXX Version: 20160927
# XXX


function admin_subprocs
{
integer num
while read num; do
(($num)) && echo $num || break
done
}

typeset -r MYNAME="$(basename $0 .sh)"
integer DURCHLAEUFE=${DURCHLAEUFE:-10}
echo "$MYNAME: ANFANG."
echo "$MYNAME: $DURCHLAEUFE Durchläufe"

integer -r parallel=${1:-3}
integer count=0 num

function do_parallel {
integer mynum=$1
echo -e "$mynum\c"
(yes | head -$(($RANDOM)) | wc -c >/dev/null) && print -p $mynum &
return 0
}

echo "$MYNAME: $parallel Unterprozesse"
# Co-Prozess zur Verwaltung der Paralleljobs starten
admin_subprocs |&

# ILLimitTypes auslesen und parallel verarbeiten
while (($DURCHLAEUFE)); do
if (($count < $parallel)); then
num=$((count += 1))
else
if ! read -p num; then # freie Prozessnummer aus Co-Prozess lesen
echo -e "\n$MYNAME: Das Huhn ist tot!"
exit 1
fi
fi
do_parallel $num # Funktion aufrufen
((DURCHLAEUFE -= 1))
done

# Auf Unterprozesse warten, indem der Co-Prozess ausgelesen wird
while (($count > 0)); do
read -p num
((count -= 1))
done
print -p 0 # Terminierung an Co-Prozess schicken

echo "$MYNAME: ENDE."
exit 0

Loading...