The case
statement is specifically intended for comparing a single string against various patterns, and doing different things depending on which it matches:
#!/bin/bash
case "$OSTYPE" in
"linux-gnu"* )
script_path="$(dirname "$(realpath -s "$0")")" ;;
"darwin"* )
script_path="$(dirname "$(pwd)")" ;;
* )
echo "Unknown OS!" >&2
exit 1 ;;
esac
Notes: each pattern is delimited with a )
at the end. You can also put a (
at the beginning, but most people don't bother. Each case ends with a double semicolon. The *
case at the end will match anything that didn't match an earlier pattern, so it functions like an else
clause in an if ... elif ...
statement.
Some other changes I made:
- It's a good idea to double-quote variable references and command substitutions (e.g.
"$(realpath -s "$0")"
instead of just $(realpath -s $0)
) to avoid weird parsing problems with some characters (mostly spaces) in values. (There are some places where it's safe to leave the double-quotes off, but it's not worth trying to remember where they are.)
- Since there are a whole bunch of all-caps names with special functions, it's safest to use lower- or mixed-case names (e.g.
script_path
instead of SCRIPT_PATH
) to avoid conflicts.
- Error and status messages (like "Unknown OS!") should generally be sent to standard error instead of standard output. I used
>&2
to redirect the message to standard error.
- When a script (or function, or program, or whatever) exits after an error, it should return a nonzero exit status to indicate that it failed. Different codes can be used to indicate different problems, but 1 is commonly used as a generic "something went wrong" code, so I used
exit 1
here.
And I recommend using shellcheck.net to scan your scripts for common mistakes. It'll save you a lot of trouble.