[gelöst] bash $? von mehreren Befehlen mit OR verknüpfen?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
mclien
Beiträge: 2468
Registriert: 06.12.2005 10:38:46
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Baustelle

[gelöst] bash $? von mehreren Befehlen mit OR verknüpfen?

Beitrag von mclien » 15.01.2013 10:52:29

In einem script kann ich ja den Rückmeldewert des letzten commandos auswerten: z.B.

Code: Alles auswählen

 
<irgendein commando>
if [ $? = 0 ];then
...
Bin jetzt auf der suche wie ich folgendes bewerkstellige:

Code: Alles auswählen

<irgendein commando1>
<irgendein commando2>
<irgendein commando3>
if [ <irgendeiner der drei $? != 0 ]; then
....
geht das direkt oder muss ich a) eine for Schleife basteln oder b) die ifAbfrage hinter jedes commando hängen?
oder c) die drei Rückmeldungen in extra Variablen stopfen und dann imn [] mit || auswerten?
Zuletzt geändert von mclien am 16.01.2013 11:40:16, insgesamt 1-mal geändert.

syssi
Beiträge: 2951
Registriert: 24.12.2010 16:50:59
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Rheinland

Re: bash $? von mehreren Befehlen mit OR verknüpfen?

Beitrag von syssi » 15.01.2013 11:14:39

Wie waere es mit:

Code: Alles auswählen

<irgendein commando1>
RET1=$?
<irgendein commando2>
RET2=$?
<irgendein commando3>
RET3=$?

if  [ $RET1 -ne 0 -o $RET2 -ne 0 -o $RET3 -ne 0 ]; 
then
  echo test
fi
Zuletzt geändert von syssi am 15.01.2013 11:27:19, insgesamt 1-mal geändert.

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: bash $? von mehreren Befehlen mit OR verknüpfen?

Beitrag von peschmae » 15.01.2013 11:25:14

So direkt geht das meines Wissens nicht. Am ehsten würde ich die vorgeschlagene Variablensammlung basteln.

Im Übrigen ist die Grundvariante

Code: Alles auswählen

<irgendein commando>
if [ $? = 0 ];then
...
gleichwertig mit

Code: Alles auswählen

if ! <irgendein commando>; then
...
Oder noch kürzer:

Code: Alles auswählen

<irgendein commando> || ...
(wie in jeder anständigen Programmiersprache wird hier bei einem "or" das zweite Argument nur ausgewertet wenn das erste Argument "false" war)

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: bash $? von mehreren Befehlen mit OR verknüpfen?

Beitrag von Cae » 15.01.2013 12:55:22

Der Unterschied von a || b || c gegenueber a; a_ret=$?; b; b_ret=... ist allerdings, dass in der ersten Variante b nicht mehr ausgefuehrt wird, sobald a gescheitert ist.

Ein vielleicht sogar funktionierender Ansatz: set -e und eine trap auf EXIT. Wie sich herausstellt, ja, es geht:

Code: Alles auswählen

#!/bin/sh

a() { echo a; true; }
b() { echo b; false; }
c() { echo c; true; }

theshowmustgoon() {
	set +e;
	trap '' EXIT;
	false; # no problem
	echo "I don't exit yet";
}

trap theshowmustgoon EXIT;
set -e;

a;
b;
c;

theshowmustgoon;

echo 'real exit here';
Zuerst wird a, b und c definiert. b wird irgendwie fehlerhaft sein und einen !=0-Rueckgabewert haben. Dieser wird wegen des set -e unten aber das Skript beenden. Allerdings wird in der Zeile drueber eine Fall (trap) fuer genau dieses Ende aufgestellt. D.h. wenn das Skript eigentlich beendet werden sollte, wird trotzdem noch theshowmustgoon aufgerufen. Dies wurde oben definiert und schaltet errexit und die trap wieder ab. In dieser Funktion muss auch saemtlicher Code sein, der eigentlich direkt nach a; b; c liegen wuerde. real exit here wird nicht gedruckt:

Code: Alles auswählen

$ ./foo
a
b
I don't exit yet
$ 
Sofern b; aber nicht explodiert (weil man den Aufruf unten auskommentiert hat, wird die Funktion einfach ausgefuehrt), ohne zu beenden:

Code: Alles auswählen

$ ./foo
a
c
I don't exit yet
real exit here
$ 
Das Problem bei der Aktion ist allerdings, dass im ersten Fall c trotzdem nicht ausgefuehrt wird, man mit der Konstruktion also nur eine ein bisschen flexiblere Variante von a || b || c erreicht. :|

Gruss Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

newdeb
Beiträge: 134
Registriert: 03.02.2011 11:11:21
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Frankfurt

Re: bash $? von mehreren Befehlen mit OR verknüpfen?

Beitrag von newdeb » 15.01.2013 18:30:01

Die $? einfach addieren? (falls keine Fehlercodes <0 vorkommen)

Code: Alles auswählen

declare -i s
<irgendein commando1>; ((s+=$?))
<irgendein commando2>; ((s+=$?))
<irgendein commando3>; ((s+=$?))
if ((s)); then
  # Error
  ...

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: bash $? von mehreren Befehlen mit OR verknüpfen?

Beitrag von peschmae » 15.01.2013 18:30:18

Hmm, hatte gar nicht bedacht dass man meine Antwort auch falsch verstehen kann. Aber du hast recht, das war nicht so klar formuliert. Das || ist in dem Fall nur nützlich um ein einzelnes Kommando zu prüfen, nicht für mehrere. Also nur a || echo kaputt

Wenn man b nur ausführen will wenn a funktioniert hat, könnte man auch sowas wie a && b || echo eins von a und b kaputt machen. Oder so.

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

mclien
Beiträge: 2468
Registriert: 06.12.2005 10:38:46
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Baustelle

Re: bash $? von mehreren Befehlen mit OR verknüpfen?

Beitrag von mclien » 16.01.2013 11:39:18

syssi hat geschrieben:

Code: Alles auswählen

<irgendein commando1>
RET1=$?
<irgendein commando2>
RET2=$?
<irgendein commando3>
RET3=$?

if  [ $RET1 -ne 0 -o $RET2 -ne 0 -o $RET3 -ne 0 ];
then
  echo test
fi
peschmae hat geschrieben:So direkt geht das meines Wissens nicht.....
Doch :mrgreen:
Dank an alle.

mclien
Beiträge: 2468
Registriert: 06.12.2005 10:38:46
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Baustelle

Re: bash $? von mehreren Befehlen mit OR verknüpfen?

Beitrag von mclien » 16.01.2013 11:42:26

peschmae hat geschrieben:So direkt geht das meines Wissens nicht. Am ehsten würde ich die vorgeschlagene Variablensammlung basteln.

Im Übrigen ist die Grundvariante

Code: Alles auswählen

<irgendein commando>
if [ $? = 0 ];then
...
gleichwertig mit

Code: Alles auswählen

if ! <irgendein commando>; then
...
OK, aber wenn das comand dann sowas wie ein durch ssh getunnelter rsync mit keypaar und Variablen für die Pfade ist, wird mir das zu unübersichtlich..

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: bash $? von mehreren Befehlen mit OR verknüpfen?

Beitrag von Cae » 16.01.2013 12:11:06

peschmae hat geschrieben:gleichwertig mit

Code: Alles auswählen

if ! <irgendein commando>; then
...
Oder auch, und damit moeglicherweise uebersichtlicher:
command -a -b --arg --foo bar || {
        echo 'wah, failed!'
        # do something
}
Gruss Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: bash $? von mehreren Befehlen mit OR verknüpfen?

Beitrag von peschmae » 16.01.2013 12:49:38

mclien hat geschrieben:
peschmae hat geschrieben:So direkt geht das meines Wissens nicht.....
Doch :mrgreen:
Naja, je nach Definition von direkt. Ich finde die Lösung recht indirekt - erst alle $? aufsammeln und dann alle Prüfen. Man würde ja erwarten das das irgendwie in einem Schritt geht, nur kann das bash-if halt selber keine logischen Verknüpfungen ohne dass daran implizit auch gleich eine (nicht-)ausführung der verbleibenden Befehle geknüpft ist...

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

mclien
Beiträge: 2468
Registriert: 06.12.2005 10:38:46
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Baustelle

Re: [gelöst] bash $? von mehreren Befehlen mit OR verknüpfen

Beitrag von mclien » 16.01.2013 20:07:16

Ah, sorry ich hatte Deine Antwort in Bezug auf syssis Antwort (2.Post) gesetzt, nicht in Bezug auf Meinen Anfangspost. Dann hast Du natürlich wieder recht.

Benutzeravatar
Phineas
Beiträge: 355
Registriert: 20.06.2012 20:26:19

Re: bash $? von mehreren Befehlen mit OR verknüpfen?

Beitrag von Phineas » 16.01.2013 23:06:42

newdeb hat geschrieben:Die $? einfach addieren? (falls keine Fehlercodes <0 vorkommen)
Wenn doch, einfach addieren:

Code: Alles auswählen

<irgendein commando> || ((s++))
<irgendein commando> || ((s++))
<irgendein commando> || ((s++))
if ((s)) ; then
  echo error
fi
:wink:

Antworten