• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

GELOEST/errorlevel durch die pipe schicken moeglich ?

A

Anonymous

Gast
Hi Freunde ;-)
folgende Problematik.
------code-fetzen------------
read -sn1 num
dev=`lspci|cut -f1 -d" "|tail -n"$num"|head -n1`
if [ $? -eq 0 ]
then
-------fetzen-aus-----------
wenn der wert $num kein gueltiger wert ist, dann verweigert logischer weise tail -n"$num" die Arbeit und liefert 1 return, ABER da sich head -n1 daran nicht stoert liefert head 0 return.
Es kommt also immer ein $? -eq 0 trotz fehler von tail.
Kann man den errorlevel von tail durch eine | weiter geben ?
Ich habe das problem umgangen, wuerde mich aber ueber jede Loesung dieses Problems freuen ;-)

Danke im vorhinein fuer alle Ideen und Loesungsvorschlaege :)

Mƒg ®êïñï
 
Habe jetzt keine Lösung für die Pipe-Problematik, kann jedoch einen workaround mit sed anbieten:
Code:
num=3
lspci | sed -n 's/ .*//;'${num}p
Einziger Unterschied ist, dass sed im Gegensatz zu tail die Zeilen von oben durchnumeriert. Man könnte da aber noch einen "tac" dazwischenbauen.
 
splitte die Pipe doch auf in:
Code:
dev=`lspci|cut -f1 -d" "|tail -n"$num"`
dev=`echo "$dev"|head -n1`

dann kannst Du nach dem tail auf den Rückgabewert testen.
 
OP
A

Anonymous

Gast
Hi ;-)
Danke fuer die Tipps ;-)
Die sed Loesung gefaellt mir sehr gut#fg#
Und das Aufsplitten der pipe war auch der erste Ansatz den ich realisiert habe, bis ich draufgekommen bin das ich durch einfache umstrukturierung ohnehin das Problem umgehen kann ;-)

Ich habe in meinen speziellen Fall also die Problematik nicht mehr, jedoch bin ich einige mal über den Umstand das eine pipe den exit-code des letzten befehls liefert gestolpert! Nach reichllicher Suche im google komme ich zu den Schluss das ein durchreichen des exit-codes durch die pipe, mit reinen bash mittel nicht realisierbar ist :(

Bis jetzt konnte ich durch spliten, andere syntax und umstrukturieren des programmablaufes immer dieses Problem umgehen;-). Dachte nur es gibt einen trick den ich nicht kenne und ich zerbrech mir umsonst den kopf #ggg#
Jedenfalls nochmals Danke ;-)

Mƒg ®êïñï
 
reini123 schrieb:
Die sed Loesung gefaellt mir sehr gut#fg#
Die Behauptung, dass die Zeilennummerierung der einzige Unterschied ist, ist nicht ganz richtig. Es gibt da nämlich eine ziemlich dreckige Falle:
Code:
tail -n5 test.txt| head -1
liefert nicht immer die 5. Zeile von unten. Wenn nämlich test.txt nur 4 Zeilen hat, wird die 4. Zeile ausgegeben. Sed würde nichts ausgeben.
 
um jetzt mal auf dieses Konkrete Problem zurückzukommen :)

wenn Du nur das 1. Feld einer bestimmten Zeile ausgeben wills (zumindest denke ich das...)

dann ist hier bei Shell-Scripts eher awk gefragt:

Code:
num=3
dev=`lspci | awk "NR==$num {print \\$1}"`

dabei gilt natürlich das gleiche wie bei dem sed-Script, ist num > Zeilen dann wird nichts ausgegeben, das kann aber leicht umgangen werden:

Code:
num=22
dev=`lspci | awk "NR==$num {print \\$1;done=1} END{if(done!=1)print \\$1}"`
 
halt, stopp: er redete von einem Shellscript und da musst Du den Backslash escapen um ihn aus der Bash an awk zu geben, wenn Du das manuell ausführen willst ist das \\ natürlich flashc ;), das einmalige escapen muss auch auf der Shell sein, beispiel:

Code:
$ num=2 && lspci | awk "NR==$num {print \$1}"
0000:00:01.0
vs:
Code:
$ num=2 && lspci | awk "NR==$num {print $1}"
0000:00:01.0 PCI bridge: Intel Corp. 82845 845 (Brookdale) Chipset AGP Bridge (rev 11)

Erklärung: da ich das awk-Script in " " setze, um $num zu ersetzen, wird natürlich $1 auf der Shell expandiert (durch das leere Wort) will ich nicht, also \$ um den Dollar an awk zu geben.

Wenn Du jetzt in einem Bashscript bist, dann ist noch eine Ebene mehr dazwischen :) also den Backslash auch noch mal escapen...
 
TeXpert schrieb:
halt, stopp ... da ich das awk-Script in " " setze, um $num zu ersetzen
Sorry, vielleicht hast du mich falsch verstanden. Die Problematik mit den Doppelten und Einfachen Hochkommas ist mir klar, ebenso die evaluierungs-Logik der Shell.

Mein Vorschlag ist in diesem Fall nur, keine doppelten Hochkommas zu verwenden und die geschweifte Klammer mit einfachen Hochkommas zu umrahmen.

Dann funktioniert es in beiden Fällen...
:D
 
ok, jetzt verstehe ich Deinen Einwand dabei ist dann aber zu beachten, dass Du damit einen üblen Hack betreibst ;)

denn das Format für awk sieht nunmal so aus:
Code:
mawk [-W option] [-F value] [-v var=value] [--] 'program text' [file ...]

und wenn Du jetzt nicht das ganze Programm durch "" oder '' bündelst, dürfen da keine Leerzeichen drin sein! daher würde ich an dieser Stelle doch überlegen, in welchem Subshelllevel das awk-Programm aufgerufen wird und entsprechend quoten ;) oder auf ein externes awk-Script zurückgreifen.
 
OP
A

Anonymous

Gast
Hallo :D
Meine Bash Versionen sind zB.
GNU bash, version 2.05b.0(1)-release (i386-redhat-linux-gnu) oder GNU bash, version 3.00.14(1)-release (i386-redhat-linux-gnu) #fg#.
Auf diesen Beiden Versionen funktioniert lspci |awk NR=="$i"'{print $1}' auch wunderbar auf GNU bash, version 2.05.0(1)-release (sparc-sun-solaris2.9) natuerlich nicht #grins# eh klar ;-)

Ich finde die Diskussion sehr interessant, aber ...... wie gesagt, es ginge mir um `echo a|ls *|ls dasgibtesnicht|echo b` wobei ich den exitstatus von ls dasgibtesnicht wissen wollte wenn es in der pipe nicht am schluss steht #fg#

Mƒg ®êïñï
Ps.: Die awk Loesung ist super, vorallen wenn sie mir vergekaut wird und ich nicht selbst kopfschmerzen von der awk-syntax bekomme #LOL# zumindest einfacher als `lspci|awk '{print $1}'|dd bs=8 skip=$num count=1 2>/dev/null` hehehe
 
reini123 schrieb:
Ps.: Die awk Loesung ist super, vorallen wenn sie mir vergekaut wird und ich nicht selbst kopfschmerzen von der awk-syntax bekomme #LOL#

was hast Du gegen die Syntax? ich finde die recht übersichtlich, insbesondere wenn Du die in eine eigene Datei auslagerst...


das unterschiedliche Verhalten muss nicht an der Shell liegen, es gibt auch verschiedene awk-Versionen...
 
OP
A

Anonymous

Gast
naja,
sollte mir mal irgend ein howto zum awk ansehen, die manpage ist zumindest fuer mich muehsam #fg# leider kommt man auf hpux oder solaris eh nicht darum herum.

Mƒg ®êïñï
 
reini123 schrieb:
sollte mir mal irgend ein howto zum awk ansehen,
Mit awk machst du sicher nichts verkehrt, da es auf allen mir bekannten LINUX/UNIX-Derivaten standard und damit universell einsetzbar ist.
Einen Nachteil hat awk: Wenn es um Massendaten-Verarbeitung geht, ist es nicht gerade schnell. Deswegen greife ich mitlerweile lieber zu Perl ;-)
 
OP
A

Anonymous

Gast
Naja LINUX-Derivat mag stimmen, aber UNIX-Derivat eher nicht :(
Ich hab natuerlch einiges zum Thema awk gelesen ( zB.: hier im forum unter Nuetzlich Links ), leider jedoch trifft das weder auf Solaris, AIX oder HP-UX zu. Man weis dann zwar das der awk das eine oder andere koennen sollte, aber nicht wie die Syntax auf der Plattform auf der man gerade arbeitet lautet #fg#. Dieser Umstand kostet oft einiges an Zeit, deren verstreichen man rechtfertigen muss:( Da sich das meiste durch einfachere nicht so Komplexe Befehle realisieren laest ( auch wenns unsauber ist ), gehe ich natuerlich den Weg des geringsten wiederstandes und versuche Syntax möglichst ohne diese zwar maechtigen aber komplexen tools zu kreiern #fg#. Mir ist bewust das die Source oft doppelt so lang als noetig ist und auch manches wo Preformence erfordert ist, so nicht realsierbar ist #gg#. Dann sinkt halt meine Preformence, wenn ich auf c++ oder perl zurückgreifen muss, da ohne Handbücher und nachschlagen, kein Blumentopf mit meinen Kenntnissen zu gewinnen ist #lach#. Ich moggle mich halt so durch mit meinen bescheidenen Kenntnissen :lol:

Æhm ... tut zwar nichts zur Sache, aber hatt wer von Euch zufällig einen Rechner mit AMI-Bios und Linux am laufen ? Bräuchte die Ausgabe von `dd if=/dev/mem bs=1k count=256 skip=768 2>/dev/null|string -n 8|grep BIOS`. Bei Phoenix und Award hab ich die gewuenschte Ausgabe !!!

Mƒg ®êïñï
 
also awk selber (also das was hier: V. Aho, B. W. Kernighan, Peter J. Weinberger : The AWK Programming Language, Addison-Wesley 1988) beschrieben ist, sollte 1:1 auf allen awks laufen können. nawk, gawk und Co sind weiterentwicklungen...

BTW: richtig übergreifend ist auch mit Shellprogramming nicht immer möglich...
 
TeXpert schrieb:
BTW: richtig übergreifend ist auch mit Shellprogramming nicht immer möglich...
Wem sagst du das! SCO UnixWare hat mich in dieser Beziehung schon einiges an Nerven gekostet. Habe schon eine Liste mit den Unterschieden geschrieben...
 
OP
A

Anonymous

Gast
Hi :D
reini123 schrieb:
Ich hab natuerlch einiges zum Thema awk gelesen ( zB.: hier im forum unter Nuetzlich Links )
Genau das habe ich gelesen unter nuetzliche Links #fg#, trotzdem Danke.
Was das eigentliche Thema betrifft: GELOEST #gg# war aber muehsam und werde ich sicher nicht anwenden ;-)
Code:
exec 3>&1;exec 4>&1;eval `((lspci;if [ $? -ne 0 ];then echo "exit=1" >&4;fi)|(cut -f1 -d" ";if [ $? -ne 0 ];then echo "exit=1" >&4;fi)|(tail -n5;if [ $? -ne 0 ];then echo "exit=1" >&4;fi)|(head -n1;if [ $? -ne 0 ];then echo "exit=1" >&4;fi)) 4>&1>&3`;echo $exit
Wobei ich einen Pseudo exit-code von 1 per $exit durchreiche #gg#
Danke für die zahlreichen Antworten auch wenn diese nicht unbedingt das Thema betroffen haben :lol:

Mƒg ®êïñï

Ps.: NACHTRAG
hab inzwischen dazugelernt #fg# und die Lösung ist noch einfacher :lol:
Code:
pipe|pipe|pipe|pipe;echo "${PIPESTATUS[*]}"
liefert im gutfall
0 0 0 0 was leicht über eine for schleife ausgewertet werden kann !
 
Oben