Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
[solved] Bash-/Pythonproblem: Exitstatus pipen
View unanswered posts
View posts from last 24 hours
View posts from last 7 days

 
Reply to topic    Gentoo Forums Forum Index Deutsches Forum (German)
View previous topic :: View next topic  
Author Message
musv
Advocate
Advocate


Joined: 01 Dec 2002
Posts: 3333
Location: de

PostPosted: Tue May 22, 2018 9:43 am    Post subject: [solved] Bash-/Pythonproblem: Exitstatus pipen Reply with quote

Hi,

ich sitze momentan an einer Aufgabe, bei der ich noch keine Lösung gefunden hab. Konkret geht es um ein Wrapperscript, dass die Ausgabe und den Exitstatus eines vorhergehenden Scriptes auswerten und später an einen anderen Server weiterleiten soll.

Vorabtest mit PIPESTATUS:
Code:

true | false; echo ${PIPESTATUS[@]}
0 1


Alle freuen sich. Jetzt bauen wir uns ein Script;
schreibwasmitstatus:
#!/bin/bash
echo "Das ist die Ausgabe"
exit 3

Und dann die Ausgabe:
Code:
./schreibwasmitstatus; echo ${PIPESTATUS[@]}
Das ist die Ausgabe.
3


Auch das ist noch hübsch. Jetzt versuchen wir noch das Auswertungsscript mit unterzubringen:
pipe_status:
#!/bin/bash
echo $?
echo ${PIPESTATUS[@]}
echo $(cat /dev/stdin)


Und dann der Versuch:
Code:
./schreibwasmitstatus | ./pipe_status
0
0
Das ist die Ausgabe.


Tja, und hier komm ich nicht weiter. Wie krieg ich den Exitstatus 3 meines ersten Scriptes in meinem zweiten Script ausgelesen?

Um das Ganze noch etwas komplizierter zu machen, muss ich das 2. Script in Python umsetzen. Aber das ändert erst mal nichts an der Problematik, dass ich überhaupt erst mal den Exit-Status im Script benötige.

Natürlich könnte ich jetzt den Namen des ersten Scripts an das zweite übergeben und über das zweite ausführen lassen (eval usw.), aber das ist weniger elegant und vermutlich auch unsicherer. Irgendwelche Ideen?


Last edited by musv on Wed May 23, 2018 4:52 pm; edited 1 time in total
Back to top
View user's profile Send private message
schmidicom
Veteran
Veteran


Joined: 09 Mar 2006
Posts: 1914
Location: Schweiz

PostPosted: Tue May 22, 2018 2:57 pm    Post subject: Reply with quote

Ist jetzt nur so eine Vermutung:
Laut der von dir verlinkten Seite enthält $PIPESTATUS den Status der zuletzt ausgeführten Pipe, die Pipe in deinem letzten Beispiel ist während du den Inhalt von $PIPESTATUS ausgibst aber noch am laufen und gar nicht fertig.
_________________
Lenovo - ThinkPad P16s Gen 2 - 21K9CTO1WW
Back to top
View user's profile Send private message
mike155
Advocate
Advocate


Joined: 17 Sep 2010
Posts: 4438
Location: Frankfurt, Germany

PostPosted: Tue May 22, 2018 3:15 pm    Post subject: Reply with quote

Quote:
./schreibwasmitstatus | ./pipe_status
Wie krieg ich den Exitstatus 3 meines ersten Scriptes in meinem zweiten Script ausgelesen?

Gar nicht - jedenfalls nicht, wenn Du die beiden Scripte über eine Pipe verknüpfst. In diesem Fall werden die beiden Scripte als unabhängige Kind-Prozesse von der Shell gestartet - und keines der beiden Prozesse kann den Exit-Code des anderen Prozesses lesen. Einmal ganz abgesehen davon, dass der zweite Prozess möglicherweise schon beendet wird, bevor des erste Prozess seinen ERC zurückgegeben hat.

Eine Möglichkeit wäre, dass Dein erstes Script direkt vor dem exit einen speziellen String nach stdout schreibt, z.B. "*Exit Code: 3*" und der zweite Prozess diesen String erkennt und sich den Exit-Code dann aus diesem String holt. Andere Möglichkeiten sind: IPC zwischen den beiden Prozessen, Umweg über die aufrufende Shell, Start der beiden Programme über einen anderen Mechanismus als eine Pipe, usw.
Back to top
View user's profile Send private message
musv
Advocate
Advocate


Joined: 01 Dec 2002
Posts: 3333
Location: de

PostPosted: Tue May 22, 2018 8:17 pm    Post subject: Reply with quote

mike155 wrote:
In diesem Fall werden die beiden Scripte als unabhängige Kind-Prozesse von der Shell gestartet - und keines der beiden Prozesse kann den Exit-Code des anderen Prozesses lesen.

Hmm, ok, leuchtet ein.

mike155 wrote:
Eine Möglichkeit wäre, dass Dein erstes Script direkt vor dem exit einen speziellen String nach stdout schreibt, z.B. "*Exit Code: 3*"

Tja, das geht leider nicht. Die Scripte, die die Ausgabe und den Exit-Code liefern, sind unveränderlich.

Wahrscheinlich werde ich den Aufruf dann so abändern:
Code:
echo 'script 1 param1..n' |  ./script 2

Script 2 führt dann script 1 aus und kann entsprechend auch den Exit-Code evaluieren.

Danke.
Back to top
View user's profile Send private message
mike155
Advocate
Advocate


Joined: 17 Sep 2010
Posts: 4438
Location: Frankfurt, Germany

PostPosted: Tue May 22, 2018 8:51 pm    Post subject: Reply with quote

Wie wär's mit einer temporärern Zwischendatei?
Code:
./schreibwasmitstatus > /tmp/datei
export erc_of_schreibwasmitstatus=$?
./pipe_status < /tmp/datei
rm /tmp/datei

In pipe_status kannst Du dann $erc_of_schreibwasmitstatus auswerten. Oder Du übergibst $erc_of_schreibwasmitstatus als CLI-Parameter an pipe_status...
Das geht natürlich nur, wenn schreibwasmitstatus und pipe_status nicht parallel laufen müssen.
Back to top
View user's profile Send private message
schmidicom
Veteran
Veteran


Joined: 09 Mar 2006
Posts: 1914
Location: Schweiz

PostPosted: Wed May 23, 2018 6:34 am    Post subject: Reply with quote

Wenn das erste Script nicht geändert werden darf wie wäre es mit so etwas als zweites Script.
run.py:
#!/usr/bin/python3
# coding: utf8
import argparse
import os
import sys

parser = argparse.ArgumentParser()
parser.add_argument("script")
args = parser.parse_args()

x = os.system(args.script)
sys.exit(x)

Ausführen mit "run.py ./schreibwasmitstatus"
Dieses Python-Script beendet sich selbst mit dem selben Exitcode wie das von ihm ausgeführte "script"
_________________
Lenovo - ThinkPad P16s Gen 2 - 21K9CTO1WW
Back to top
View user's profile Send private message
tazinblack
Veteran
Veteran


Joined: 23 Jan 2005
Posts: 1144
Location: Baden / Germany

PostPosted: Wed May 23, 2018 1:02 pm    Post subject: Reply with quote

Hab gerade wenig Zeit, deshalb TLDR :-)

Also bei mir geht das hier:

Script1:
Code:
#!/bin/bash

  echo "Script1"
  exit 3



Script2:
Code:
#!/bin/bash

  ./script1
  STATUS=$?

  echo "Ergebnis von Script1 : ${STATUS}"

  exit 0


Wenn ich 1 ausführe:
Code:
./script2
Script1
Script2 ...
Ergebnis von Script1 : 3


Ich hoffe das hilft. Wichtig ist, dass vor $? nichts anderes ausgeführt wird, sonst hast Du davon das Ergebnis.
_________________
Gruß / Regards
tazinblack
_______________________________________________________
what's the point in being grown up if you can't be childish sometimes
Back to top
View user's profile Send private message
mike155
Advocate
Advocate


Joined: 17 Sep 2010
Posts: 4438
Location: Frankfurt, Germany

PostPosted: Wed May 23, 2018 1:20 pm    Post subject: Reply with quote

Quote:
Also bei mir geht das hier:

Sehr hübsch! :-)

Aber das war nicht die Frage. Die Frage war: wenn man zwei Programme über eine Pipe verknüpft: wie kann dann das zweite Programm den Exit-Status des ersten Programms erhalten? Nebenbedingung: das erste Programm kann/darf nicht geändert werden.
Back to top
View user's profile Send private message
mike155
Advocate
Advocate


Joined: 17 Sep 2010
Posts: 4438
Location: Frankfurt, Germany

PostPosted: Wed May 23, 2018 1:37 pm    Post subject: Reply with quote

Man könnte es mit einer Sub-Shell lösen:
Code:
#! /bin/bash
(    
    schreibwasmitstatus
    echo "ERC: $?"
) | pipe_status

Das zweite Programm (pipe_status) müsste dann nur nach einem String der Form "ERC: [0-9]+" suchen und aus diesem den Fehlercode entnehmen.
Back to top
View user's profile Send private message
musv
Advocate
Advocate


Joined: 01 Dec 2002
Posts: 3333
Location: de

PostPosted: Wed May 23, 2018 4:51 pm    Post subject: Reply with quote

Ich zitier mich mal selbst:

musv wrote:

Wahrscheinlich werde ich den Aufruf dann so abändern:
Code:
echo 'script 1 param1..n' |  ./script 2

Script 2 führt dann script 1 aus und kann entsprechend auch den Exit-Code evaluieren.


Das entspricht grob dem, was ihr vorgeschlagen hattet. Das Script als Parameter zu übergeben, hatte ich auch schon implementiert. Also so in der Art:

Code:
./script2 'script1 param1..n'

Das klappt auch.

Es wär halt einfach, elegant und schön gewesen, wenn es mit so wenig wie möglich Schreibarbeit und potentiellen Fehlerquellen beim Aufruf selbst geklappt hätte.

Nur zur Info: Der Anwendungsfall ist ein Monitoringsystem (Icinga), bei dem halt die Check-Scripte teilweise auf dem zu überwachenden Rechner lokal ausgeführt werden und aufgrund von Firewallregeln die Ergebnisse nicht an de Masterserver zurückgesendet werden können.

Danke soweit an alle. Das Thema ist damit für mich soweit nöitg geklärt.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Deutsches Forum (German) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum