Case statements evaluate to strings

I caught a functional programming error, so naturally nothing good is enough for me.;)

So in bash you can write:

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

but I'm afraid of typos, so I prefer to write:

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

The second form is invalid because the case evaluates the exit code of the last command executed, which is not at all what I'm looking for.

Are there any easy hacks to achieve what I 'm looking for?

+10
bash functional-programming case notation case-statement
source share
3 answers

If you are sure that the status will be only one line, you can do something similar with sed:

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

You can also get something to work with bash's built-in replacement. This almost works (I don't know how to get an exact match):

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

If your goal is to be more “functional” (and so that your code is no longer sealed), you can do this:

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

Although, frankly, bash is probably one of the worst languages ​​to try and be functional. It was truly designed with more imperative thinking, as evidenced by the fact that you cannot easily compose expressions. Look in the second code snippet, how did I have to break it into two separate statements? If bash were designed to work, you could write something like this:

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

But this does not work.

I suggest using only bash for simpler scripts, and for more complex things, use something like Python or Ruby. They will allow you to write more functional code without having to constantly struggle with the language.

+11
source share
 status="baz" status=$(case $status in "foo") echo "bar" ;; "baz") echo "buh" ;; *) echo $status ;; esac) echo "status: $status" 

Exit

 $ ./shell.sh status: buh 
+3
source share

Bash 4 has associative 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 
-one
source share

All Articles