Gibt es eine Möglichkeit, so etwas zu tun
int a = (b == 5) ? c : d;
mit Bash?
Gibt es eine Möglichkeit, so etwas zu tun
int a = (b == 5) ? c : d;
mit Bash?
Das Folgende scheint für meine Anwendungsfälle zu funktionieren:
$ tern 1 YES NO
YES
$ tern 0 YES NO
NO
$ tern 52 YES NO
YES
$ tern 52 YES NO 52
NO
und kann in einem Skript wie folgt verwendet werden:
ERGEBNIS=$(tern 1 YES NO)
echo "Das Ergebnis ist $ERGEBNIS"
#!/usr/bin/env bash
function show_help()
{
ME=$(basename "$0")
IT=$(cat < 0
FALSE_VALUE=${4:-0}
function main
{
if [ "$1" == "$FALSE_VALUE" ] || [ "$1" = '' ]; then
echo $3
exit;
fi;
echo $2
}
main "$1" "$2" "$3"
Hey @ - das ist der Name des Bash-Skripts - speichern Sie diesen "tern"-Abschnitt oben in einer Datei namens "tern" und führen Sie chmod 700 tern
im selben Ordner aus. Jetzt haben Sie einen tern
-Befehl in Ihrem Terminal.
Hier ist eine allgemeine Lösung, die
Test mit numerischem Vergleich
a=$(if [ "$b" -eq 5 ]; then echo "$c"; else echo "$d"; fi)
Test mit String-Vergleich
a=$(if [ "$b" = "5" ]; then echo "$c"; else echo "$d"; fi)
Diese Lösung hat denselben Mangel, den ivan_pozdeev beschreibt, nämlich dass bei dieser Lösung echo "false"
auftreten kann, wenn ping
erfolgreich ist, aber aus irgendeinem Grund, wie unwahrscheinlich auch immer, der Teil echo "true"
einen nicht-nullen Exit-Status zurückgibt (siehe ShellCheck SC2015). Um echo "false"
nur dann auszugeben, wenn ping
fehlschlägt, unabhängig vom Exit-Status von echo "true"
, verschiebe die erste Klammersetzung {
an den Anfang: { (ping -c1 localhost&>/dev/null) && echo "true"; } || { echo "false"; }
.
Einige Leute haben bereits einige schöne Alternativen vorgestellt. Ich wollte die Syntax so nah wie möglich bringen, also schrieb ich eine Funktion namens ?
.
Dies ermöglicht die Syntax:
[[ $x -eq 1 ]]; ? ./script1 : ./script2
# oder
? '[[ $x -eq 1 ]]' ./script1 : ./script2
In beiden Fällen ist das :
optional. Alle Argumente, die Leerzeichen enthalten, müssen in Anführungszeichen stehen, da sie mit eval
ausgeführt werden.
Wenn die oder Klauseln keine Befehle sind, gibt die Funktion den entsprechenden Wert mit echo
aus.
./script; ? Erfolg! : "Fehler :("
?() {
lokale letzteRück=$?
if [[ $1 == --help || $1 == -? ]]; then
echo $'\e[37;1mVerwendung:\e[0m
? [] [:]
Wenn \e[37;1m\e[0m und/oder \e[37;1m\e[0m keine gültigen Befehle sind, werden ihre Werte
in stdOut ausgegeben, andernfalls werden sie ausgeführt. Wenn \e[37;1m\e[0m nicht
angegeben ist, wird der Rückgabecode ($?) des vorherigen Statements ausgewertet.
\e[37;1mBeispiele:\e[0m
myVar=$(? "[[ $x -eq 1 ]] foo bar)
\e[32;2m# myVar wird auf "foo" gesetzt, wenn x 1 ist, ansonsten wird es auf "bar" gesetzt\e[0m
? "[[ $x = *foo* ]] "cat hello.txt" : "cat goodbye.txt"
\e[32;2m# führt cat auf "hello.txt" aus, wenn x das Wort "foo" enthält, sonst führt es cat auf
# "goodbye.txt" aus\e[0m
? "[[ $x -eq 1 ]] "./script1" "./script2"; ? "Erfolgreich!" "Gescheitert :("
\e[32;2m# Wenn x = 1 ist, führt script1 aus, sonst script2. Wenn das Skript erfolgreich ausgeführt wird, wird
# "Erfolgreich!" gedruckt, ansonsten wird "gescheitert" gedruckt.\e[0m'
zurück
elif ! [[ $# -eq 2 || $# -eq 3 || $# -eq 4 && $3 == ':' ]]; then
1>&2 echo $'\e[37;1m?\e[0m benötigt 2 bis 4 Argumente
\e[37;1mVerwendung\e[0m: ? [] [:]
Führen Sie \e[37;1m? --help\e[0m für weitere Details aus'
zurück 1
fi
lokale cmd
if [[ $# -eq 2 || $# -eq 3 && $2 == ':' ]]; then
cmd="[[ $lastRet -eq 0 ]]"
else
cmd="$1"
shift
fi
if [[ $2 == ':' ]]; then
eval "set -- '$1' '$3'"
fi
lokale ergebnis=$(eval "$cmd" && echo "$1" || echo "$2")
if command -v ${result[0]} &> /dev/null; then
eval "${result[@]}"
else
echo "${result[@]}"
fi
}
Natürlich können Sie den Hilfetext entfernen, wenn Sie möchten, dass das Skript kürzer wird.
EDIT: Ich war nicht darüber im Bilde, dass ?
als Platzhalterzeichen in einem Dateinamen fungiert. Anstatt wie *
eine beliebige Anzahl von Zeichen abzugleichen, gleicht es genau ein Zeichen ab. Wenn Sie also eine Datei mit einem einzelnen Zeichen in Ihrem Arbeitsverzeichnis haben, wird bash versuchen, den Dateinamen als Befehl auszuführen. Ich bin mir nicht sicher, wie man das umgehen kann. Ich dachte, die Verwendung von command "?" ...args
könnte funktionieren, aber leider nicht.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
1 Stimmen
@dutCh's Antwort zeigt, dass
bash
tatsächlich etwas Ähnliches wie den "ternären Operator" hat, jedoch wird dies inbash
als "konditionaler Operator"expr?expr:expr
bezeichnet (sieheman bash
Abschnitt "Arithmetische Auswertung"). Beachten Sie, dass derbash
"konditionale Operator" knifflig ist und einige Fallstricke hat.0 Stimmen
Bash verfügt über einen ternären Operator für ganze Zahlen und er funktioniert innerhalb des arithmetischen Ausdrucks
((...))
. Siehe Shell-Arithmetik.2 Stimmen
Genau wie @codeforester erwähnt hat, funktioniert der ternäre Operator mit arithmetischer Expansion
$(( ))
und arithmetischer Auswertung(( ))
. Siehe auchhttps://mywiki.wooledge.org/ArithmeticExpression
.