Ich suche nach einer Möglichkeit, bedingte Zuweisungen in Bash zu erstellen:
In Java sieht es so aus:
int variable= (condition) ? 1 : 0;
Antworten:
Gemäß Jonathans Kommentar:
variable=$(( 1 == 1 ? 1 : 0 ))
Ich habe die ursprüngliche Antwort überarbeitet, die nur echoden Wert des Bedingungsoperators hatte und tatsächlich keine Zuordnung zeigte.
(( variable = 1 == 1 ? 1 : 0 ))oder (( variable = (1 == 1) ? 1 : 0 ))Aber es könnte argumentiert werden, dass es besser lesbar ist, wie in der Antwort angegeben.
Wenn Sie eine Möglichkeit zum Definieren von Standardeinstellungen in einem Shell-Skript wünschen, verwenden Sie folgenden Code:
: ${VAR:="default"}
Ja, die Zeile beginnt mit ':'. Ich verwende dies in Shell-Skripten, damit ich Variablen in ENV überschreiben oder die Standardeinstellung verwenden kann.
Dies hängt damit zusammen, dass dies mein häufigster Anwendungsfall für diese Art von Logik ist. ;]
myvar="default" && [[ <some_condition_is_true> ]] && myvar="non-default"
echte Beispiele:
DELIM="" && [[ "$APP_ENV_RESOLVED" != "" ]] && DELIM=$INNER_DELIM
Die Bedingung kann auch "((...))" sein:
filepath=/proc/drbd && (( $# > 0 )) && filepath=$1
Zusätzlich zu den anderen allgemeineren Antworten (insbesondere gemäß Jonathans Kommentar und Kevins allgemeinerer Antwort [die auch Zeichenfolgen unterstützt]) möchte ich die folgenden zwei Lösungen hinzufügen:
0oder 1basierend auf der Bedingung:(Wie das Beispiel der Frage zeigt.)
Die allgemeine Form würde lauten
(condition); variable=$?;
Dabei $variableergibt sich entweder 0oder 1und conditionkann ein beliebiger gültiger bedingter Ausdruck sein .
ZB eine Variable prüfen ...
[[ $variableToCheck == "$othervariable, string or number to match" ]]
variable=$?
... oder die Existenz einer Datei überprüfen ...
[ -f "$filepath" ]
fileExists=$?
... oder überprüfen Sie den Zahlenwert von $myNumber:
(( myNumber >= 1000000000 ))
is_huge_number=$?
variablewird auf jeden Fall deklariert , anders als in Griffons Antwort : [ -z "$variable" ] && variable="defaultValue"
Bitte beachten Sie: In Bash $?enthält die spezielle Variable immer den Exit-Code der zuvor ausgeführten Anweisung (oder des Anweisungsblocks; weitere Informationen finden Sie in der Man-Bash ). Als solches wird ein positives Ergebnis im Allgemeinen durch den Wert dargestellt0 , nicht 1(siehe meinen Kommentar unten , danke Assimilater für den Hinweis ). Wenn also die Bedingung wahr ist (zB [[2 eq 2]]), dann $?=0.
Wenn Sie stattdessen 0 oder 1 in Ihrer Variablen benötigen (z. B. um zu drucken oder mathematische Berechnungen durchzuführen), müssen Sie eine boolesche Negation mit einem führenden Ausrufezeichen verwenden (wie von GypsySpellweaver in den Kommentaren unten hervorgehoben): ( ! condition ); variable=$?oder ! ( condition ); variable=$?. (Die Lesbarkeit in Bezug auf das, was passiert, ist jedoch möglicherweise weniger offensichtlich.)
Eine andere mögliche Lösung von Jonathan wäre variable=$(( 1 == 1 ? 1 : 0 ))- was jedoch darin besteht, eine Unterschale zu erstellen.
Wenn Sie die Erstellung eines Subshels vermeiden, eine gute Lesbarkeit gewährleisten oder beliebige Bedingungen haben möchten, verwenden Sie eine der folgenden Lösungen.
Wie in den meisten anderen Antworten wird es wie folgt angepasst:
(condition) \
&& variable=true \
|| variable=false
zB wie in
[[ $variableToCheck == "$othervariable, string or number to match" ]] \
&& variable="$valueIfTrue" \
|| variable="$valueIfFalse"
oder um 1 in einer positiven Prüfung und 0 bei einem Fehler zu erhalten (wie im Beispiel der Frage):
[[ $variableToCheck == "$othervariable, string or number to match" ]] \
&& variable=1 \
|| variable=0
(Für das letzte Beispiel kann - wie bereits in den obigen Anmerkungen erwähnt - dasselbe mit einer booleschen Negation unter Verwendung eines führenden Ausrufezeichens erreicht werden:
[[ ! $variableToCheck == "$othervariable, string or number to match" ]]
variable=$?
myvar="default" && [[ <some_condition_is_true> ]] && myvar="non-default" , und$valueIfTruebedingt ausgewertet nur , wenn nötig ,variable=$((i++)), oder{ variable=$1; shift; }variable=$(find / -type f -name ListOfFilesWithThisNameOnMySystem)variablewird auf jeden Fall deklariert , anders als in Griffons Antwort : [ -z "$variable" ] && variable="defaultValue"[ "$1" == "--all" ] ; allperiods=$? ; echo $allperiods
executable && executesWhenOk || executesWhenNotOkund in unserem Szenario ist der Test die "ausführbare Datei" (oder Anweisung, um genau zu sein), und die spezielle Variable $?enthält den Ergebniscode der letzten Anweisung. hoffe das hilft zu klären.
1ist trueund 0ist false, kann in diesem Fall mit dem NOT leicht erreicht werden ! , indem Operator auf den Ausdruck angewendet wird. Entweder innerhalb oder außerhalb des 'Ausdrucks'. ( ! condition ); variable=$?oder ! ( condition ); variable=$?Eine solche, [ ! -f "$filepath" ]; fileExists=$?die als Programmierer funktioniert, ist gewohnt: 1 Datei existiert und 0 Datei fehlt.
Ich wollte eine bedingte Aufgabe mit Strings machen und endete mit:
SOWHAT=$([ "$MYVALUE" = "value" ] && echo "YES" || echo "NO")
Ein großes Dankeschön an @Demosthenex und insbesondere an @Dennis Williamson für die kürzeste und einfachste Lösung, die ich je gesehen habe. Überlassen Sie es dem Bash , um eine Reihe von Klammern für eine einfache ternäre Zuordnung zu benötigen . Ahh, die 60er ! Und um alles in einem Beispiel zusammenzufassen ...
echo $BASHRULES; # not defined
# no output
: ${BASHRULES:="SCHOOL"} # assign the variable
echo $BASHRULES # check it
SCHOOL # correct answer
: ${BASHRULES="FOREVER?"} # notice the slightly different syntax for the conditional assignment
echo $BASHRULES # let's see what happened!
SCHOOL # unchanged! (it was already defined)
Ich habe das vor langer Zeit geschrieben. In diesen Tagen würde ich mich wahrscheinlich mehr über eine Lösung wie ... freuen.
PLATFORM=iphonesimulator
OTHERSDK=iphone && [[ $PLATFORM=~os ]] \
&& OTHERSDK+=simulator \
|| OTHERSDK+=os
$OTHERSDK⇥iphoneos
bashKöcher haben sollte. Für Neugierige und / oder Unglückliche, die ihn hier entdecken, spielt diese Art der bedingten Zuweisung auch gut mit exportAussagen - die Sie zwischen das Doppelpunktpräfix und den Dollar setzen. Zeichen Aussage-y Teil, zB: export ${YO_DOGG:="global environment default"}
iphonesimulatordass die osobige Lösung enden würde , da sie die Zeichenfolge nicht enthält OTHERSDK=iphonesimulator.
Wenn Sie einen Wert zuweisen möchten, sofern die Variable nicht leer ist, verwenden Sie Folgendes:
[ -z "$variable" ] && variable="defaultValue"
Sie können sich auch gegenseitig auf die Bedingung stellen []
: ${variable:='defaultValue'}
ein anderer Weg
case "$variable" in
condition ) result=1;;
*) result=0;;
esac
variable=$(( 1 == 1 ? 1 : 0 ))solange um das erste '=' - Zeichen keine Leerzeichen vorhanden sind. Sie können danach alle Leerzeichen weglassen und es funktioniert auch - aber denken Sie an die Lesbarkeit.