2010-02-17 10 views
7

Ich habe den funktionalen Programmierfehler gefangen, also ist natürlich nichts mehr gut genug für mich. ;)bash case statements bewerten zu Strings

So konnte man in der Bash schreiben:

case $status in 
    "foo") status="bar" ;; 
    "baz") status="buh" ;; 
    *) status=$status ;; 
esac 

aber ich bin der Tippfehler Angst, so würde ich lieber schreiben:

status=case $status in 
    "foo") "bar" ;; 
    "baz") "buh" ;; 
    *) $status ;; 
esac 

Die zweite Form ist Ungültig, da der Fall den Exit-Code des zuletzt ausgeführten Befehls auswertet. Das ist gar nicht das, wonach ich suche.

Gibt es einfache Hacks zu erreichen, was ich suche am?

+0

sind Sie wollen nur eine Funktion schreiben? – thecoshman

+0

Wenn Sie Angst vor Tippfehlern haben, verwenden Sie ['set -u'] (https://sipb.mit.edu/doc/safe-shell/) am Anfang Ihres Programms. – ceving

Antwort

9

Wenn Sie sicher, dass Status sind nur eine Zeile sein, könnten Sie so etwas wie dies mit sed tun:

status=$(echo "$status" | sed -e 's:^foo$:bar:' -e 's:^baz$:buh:') 

Sie können auch in der Lage sein, etwas zu bekommen, mit bash eingebautem Ersatz zu arbeiten. Diese fast Werke (ich weiß nicht von irgendeiner Weise nur zu bekommen genau passend):

status=${status/foo/bar} 
status=${status/baz/buh} 

Wenn Ihr Ziel ist nur mehr „funktional“ zu sein (und nicht Ihren Code Typo sicher zu machen), können Sie dies tun:

status=$(
    case "$status" in 
    ("foo") echo "bar" ;; 
    ("baz") echo "buh" ;; 
    (*) echo "$status" ;; 
    esac) 

Obwohl ehrlich gesagt, ist bash wahrscheinlich eine der schlimmsten Sprachen zu versuchen und funktional zu sein, es war wirklich eine zwingende Mentalität entwickelt, durch die Tatsache verdeutlichte, wie Sie können. Komponieren Sie keine Ausdrücke. Sehen Sie im zweiten Codefragment, wie ich es in zwei separate Anweisungen aufteilen musste? Wenn bash entworfen wurde funktional sein würden Sie in der Lage sein, so etwas wie diese, anstatt zu schreiben:

status=${{status/baz/buh}/foo/bar} 

Aber das tut nicht Arbeit.

Ich würde vorschlagen, nur Bash für einfachere Skripte zu verwenden, und für kompliziertere Dinge verwenden Sie etwas wie Python oder Ruby. Sie werden Ihnen mehr Funktionscode schreiben lassen, ohne ständig mit der Sprache ringen zu müssen.

+0

Weise, die Frage nicht zu beantworten und viele irrelevante Informationen hinzuzufügen. – mbac32768

+0

Mit zsh können Sie geschachtelte Parametererweiterungen wie das letzte Beispiel ausführen. –

+9

@ mbac32768 Soweit ich das beurteilen kann, habe ich deine Frage dreimal beantwortet. Wenn Sie nicht zustimmen, müssen Sie vielleicht Ihre Frage neu formulieren, oder Sie könnten zumindest erklären, warum diese Lösungen für Sie nicht funktionieren. Snarky zu bekommen, wenn jemand versucht, dir zu helfen, ist irgendwie lahm. –

-1

Bash 4 hat assoziative Arrays:

# setup 
unset vals i 
indices=(foo baz) 
val=(bar buh) 
declare -A vals    # associative 
for index in ${indices[@]} 
do 
    vals[$index]=${val[i++]} 
done 

$ # demos 
$ status="foo" 
$ status=${vals:-$status} 
$ echo $status 
bar 
$ status="not found" 
$ status=${vals:-$status} 
$ echo $status 
not found 
+0

Soll man assoziative Arrays in bash4 wirklich initialisieren? –

+1

@Charles: Es ist eine Möglichkeit, die für diese Demo sinnvoll ist. Ich hätte zum Beispiel "für einen Index in foo baz" anstelle eines Arrays verwenden können. Oder eine direkte Massenzuordnung gemacht oder aus einer Datei gelesen haben. Nach was fragen Sie besonders? –

2
status="baz" 
status=$(case $status in 
    "foo") echo "bar" ;; 
    "baz") echo "buh" ;; 
    *) echo $status ;; 
esac) 
echo "status: $status" 

Ausgang

$ ./shell.sh 
status: buh 
+1

Das ist das dritte Snippet, das ich gepostet habe, aber mit Syntaxfehlern. (Die close-parens in '$ (...)' verwirren Bash, also müssen Sie die optionale offene paren auf jeden Fall verwenden.) –

+0

was meinst du confuse bash? – ghostdog74

+0

ok, ich nehme an, Sie verwenden bash <4.0. In 4.0 denke ich, das ist behoben. – ghostdog74

Verwandte Themen