How may I concisely assign different values to a variable, depending on another variable?
Use a case
statement (portable, works in any sh
-like shell):
case "$CODE" in
[aA] ) PN="com.tencent.ig" ;;
[bB] ) PN="com.vng.pubgmobile" ;;
[cC] ) PN="com.pubg.krmobile" ;;
[dD] ) PN="com.rekoo.pubgm" ;;
* ) printf '\a\t%s\n' 'ERROR!' 'CODE KOSONG' 'MELAKUKAN EXIT OTOMATIS' >&2
exit 1 ;;
esac
I'd also recommend changing your variable names from all capital letters (like CODE
) to something lower- or mixed-case (like code
or Code
). There are many all-caps names that have special meanings, and re-using one of them by accident can cause trouble.
Other notes: The standard convention is to send error messages to "standard error" rather than "standard output"; the >&2
redirect does this. Also, if a script (or program) fails, it's best to exit with a nonzero status (exit 1
), so any calling context can tell what went wrong. It's also possible to use different statuses to indicate different problems (see the "EXIT CODES" section of the curl
man page for a good example). (Credit to Stéphane Chazelas and Monty Harder for suggestions here.)
I recommend printf
instead of echo -e
(and echo -n
), because it's more portable between OSes, versions, settings, etc. I once had a bunch of my scripts break because an OS update included a version of bash compiled with different options, which changed how echo
behaved.
The double-quotes around $CODE
aren't really needed here. The string in a case
is one of the few contexts where it's safe to leave them off. However, I prefer to double-quote variable references unless there's a specific reason not to, because it's hard to keep track of where it's safe and where it isn't, so it's safer to just habitually double-quote them.
Assuming you are using bash
release 4.0 or newer...
CODE=A
declare -A domain
domain=(
[a]=com.tencent.ig
[b]=com.vng.pubgmobile
[c]=com.pubg.krmobile
[d]=com.rekoo.pubgm
)
PN=${domain[${CODE,,}]:?ERROR! CODE KOSONG, MELAKUKAN EXIT OTOMATIS}
In the code, I define an associative array containing all the domain names, each associated with a single letter lower-case key.
The $PN
variable is assigned the domain name corresponding to the lower-cased $CODE
value (${CODE,,}
returns the value of $CODE
turned into lower case letters only) from this array, but if the $CODE
does not correspond to a valid entry in the domain
list, it exits the script with an error.
The ${variable:?error message}
parameter substitution would expand to the value of $variable
(the appropriate domain in the code) but would exit the script with the error message if the value is empty not available. You don't get exactly the same formatting of the error message as in your code, but it would essentially behave the same if $CODE
is invalid:
$ bash script.sh
script.sh: line 12: domain[${CODE,,}]: ERROR! CODE KOSONG, MELAKUKAN EXIT OTOMATIS
If you care about character count, we can shorten this further:
CODE=A
declare -A domain=( [a]=tencent.ig [b]=vng.pubgmobile [c]=pubg.krmobile [d]=rekoo.pubgm )
PN=com.${domain[${CODE,,}]:?ERROR! CODE KOSONG, MELAKUKAN EXIT OTOMATIS}
Apart from deleting unnecessary newlines, I've also removed com.
from each domain (this is instead added in the assignment to PN
).
Note that all code above would work even for a multi-character value in $CODE
(if lower-cased keys existed for these in the domain
array).
If $CODE
was a numerical (zero-based) index instead, this would simplify the code a bit:
CODE=0
domain=( com.tencent.ig com.vng.pubgmobile com.pubg.krmobile com.rekoo.pubgm )
PN=${domain[CODE]:?ERROR! CODE KOSONG, MELAKUKAN EXIT OTOMATIS}
This would additionally make it really easy to read the domain
array from an auxiliary file containing one entry per line:
CODE=0
readarray -t domain <domains.txt
PN=${domain[CODE]:?ERROR! CODE KOSONG, MELAKUKAN EXIT OTOMATIS}
If your shell allow arrays, the shortest answer should be like this example in bash:
declare -A site
site=( [a]=com.tencent.ig [b]=com.vng.pubgmobile [c]=com.pubg.krmobile [d]=com.rekoo.pubgm )
pn=${site[${code,}]}
That is assuming that $code
could only be a, b, c or d.
If not, add a test like:
case ${site,} in
a|b|c|d) pn=${site[${code,}]};;
*) pn="default site"
printf '\a\t %s\n' 'ERROR!' 'CODE KOSONG' 'MELAKUKAN EXIT OTOMATIS'
exit 1
;;
esac