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?
Die Top-Antwort [[ $b = 5 ]] && a="$c" || a="$d"
sollte nur verwendet werden, wenn Sie sicher sind, dass nach dem &&
kein Fehler auftritt, da sonst der Teil nach dem ||
fälschlicherweise ausgeführt wird.
Um das Problem zu lösen, habe ich eine Ternärfunktion geschrieben, die sich so verhält, wie sie sollte, und sogar die ?
und :
Operatoren verwendet:
Bearbeiten - neue Lösung
Hier ist meine neue Lösung, die weder $IFS
noch ev(a/i)l
verwendet.
function executeCmds()
{
declare s s1 s2 i j k
declare -A cmdTeile
declare pIFS=$IFS
IFS=$'\n'
declare results=($(echo "$1" | grep -oP '{ .*? }'))
IFS=$pIFS
s="$1"
for ((i=0; i < ${#results[@]}; i++)); do
s="${s/${results[$i]}/'\0'}"
results[$i]="${results[$i]:2:${#results[$i]}-3}"
results[$i]=$(echo ${results[$i]%%";"*})
done
s="$s&&"
let cmdTeile[t]=0
while :; do
i=${cmdTeile[t]}
let cmdTeile[$i,t]=0
s1="${s%%"&&"*}||"
while :; do
j=${cmdTeile[$i,t]}
let cmdTeile[$i,$j,t]=0
s2="${s1%%"||"*};"
while :; do
cmdTeile[$i,$j,${cmdTeile[$i,$j,t]}]=$(echo ${s2%%";"*})
s2=${s2#*";"}
let cmdTeile[$i,$j,t]++
[[ $s2 ]] && continue
break
done
s1=${s1#*"||"}
let cmdTeile[$i,t]++
[[ $s1 ]] && continue
break
done
let cmdTeile[t]++
s=${s#*"&&"}
[[ $s ]] && continue
break
done
declare lastError=0
declare skipNext=false
for ((i=0; i < ${cmdTeile[t]}; i++ )) ; do
let j=0
while :; do
let k=0
while :; do
if $skipNext; then
skipNext=false
else
if [[ "${cmdTeile[$i,$j,$k]}" == "\0" ]]; then
executeCmds "${results[0]}" && lastError=0 || lastError=1
results=("${results[@]:1}")
elif [[ "${cmdTeile[$i,$j,$k]:0:1}" == "!" || "${cmdTeile[$i,$j,$k]:0:1}" == "-" ]]; then
[ ${cmdTeile[$i,$j,$k]} ] && lastError=0 || lastError=1
else
${cmdTeile[$i,$j,$k]}
lastError=$?
fi
if (( k+1 < cmdTeile[$i,$j,t] )); then
skipNext=false
elif (( j+1 < cmdTeile[$i,t] )); then
(( lastError==0 )) && skipNext=true || skipNext=false
elif (( i+1 < cmdTeile[t] )); then
(( lastError==0 )) && skipNext=false || skipNext=true
fi
fi
let k++
[[ $k<${cmdTeile[$i,$j,t]} ]] || break
done
let j++
[[ $j<${cmdTeile[$i,t]} ]] || break
done
done
return $lastError
}
function t()
{
declare commands="$@"
find="$(echo ?)"
replace='?'
commands="${commands/$find/$replace}"
readarray -d '?' -t statement <<< "$commands"
condition=${statement[0]}
readarray -d ':' -t statement <<< "${statement[1]}"
success="${statement[0]}"
failure="${statement[1]}"
executeCmds "$condition" || { executeCmds "$failure"; return; }
executeCmds "$success"
}
executeCmds
trennt jede einzelne Anweisung voneinander ab, abgesehen von denen, die aufgrund der &&
und ||
Operatoren übersprungen werden sollen. Es verwendet []
, wenn eine Anweisung mit !
oder einer Flagge beginnt.
Es gibt zwei Möglichkeiten, Anweisungen zu übergeben:
Geben Sie die einzelnen Anweisungen unangegeben an, aber achten Sie darauf, die ;
, &&
und ||
Operatoren zu zitieren.
t ls / ? ls qqq '||' echo aaa : echo bbb '&&' ls qq
Geben Sie alle Anweisungen zitiert an:
t 'ls /a ? ls qqq || echo aaa : echo bbb && ls qq'
NB Ich fand keine Möglichkeit, die Parameter unangegeben an &&
und ||
Operatoren zu übergeben, da sie illegale Zeichen für Funktionsnamen und Aliase sind, und ich fand keine Möglichkeit, die Bash-Operatoren zu überschreiben.
Alte Lösung - verwendet ev(a/i)l
function t()
{
pIFS=$IFS
IFS="?"
read condition success <<< "$@"
IFS=":"
read success failure <<< "$success"
IFS=$pIFS
eval "$condition" || { eval "$failure" ; return; }
eval "$success"
}
t ls / ? ls qqq '||' echo aaa : echo bbb '&&' ls qq
t 'ls /a ? ls qqq || echo aaa : echo bbb && ls qq'
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
.