0

I'm trying to create a script where pretty much things got sorted out earlier in it and I'm left with the booleans I need stored in variables. I just need to run them through one last loop and I'm done

This last part I'm talking about is a less readable version of something similar to this:

                         [↑continues on top↑]
var5="$(some long operation that has different results on different systems   )"
var6="$(bc of escaping or slighly different variations on the basic set of    )"
var7="$(UNIXy commands preloaded on every system's minimal installation       )"
var8="$(e.g: <grep> Um…what else…oh yeah!  The output of these is 1 or 0  🤓  )"

varlist='$var1 $var2 ... $var8'                # ←I assume 'this' would 
                                               #  prevent it from being expanded

for ENTRY in $varlist
do
  if [ "$ENTRY" ] # ←Already a boolean
  then
    <perform operation>
  else
    <log/echo it wasn't needed or something>
  fi
done

Would that work? Or rather — is it portable? I'm jumping from macOS*, Fedora, RHEL, Debian and "appliance" FreeBSD (pfSense, OPNsense, …) nonstop. That said, I do mean Fedora, RHEL, Debian, macOS and FreeBSD, no their derivatives/downstreams/whatever so things are very predictable and stable. The most I stray from these systems is Debian on WSL and only because SSH on PowerShell is very glitchy. Am I breaking rules? Do I need to enclose variables in the variables variable (varlist, I know you just know but to avoid ambiguities) in something else? Maybe escape the $?

If you have completely different alternatives to suggest, I'm listening. I'm open for anything as long as it still is Bash.


*: pre-Catalina still with Bash by default.

3

instead of numbered variables, use an array:

entries=(
    "$(some long operation that has different results on different systems   )"
    "$(bc of escaping or slighly different variations on the basic set of    )"
    "$(UNIXy commands preloaded on every system's minimal installation       )"
    "$(e.g: <grep> Um…what else…oh yeah!  The output of these is 1 or 0  🤓  )"
)
for entry in "${entries[@]}"; do
    echo "this is entry: $entry"
done

Works with the default bash 3.2 that ships with MacOS

Trying to stringify a list of strings and then separate them is destined to fail: see http://mywiki.wooledge.org/BashFAQ/050

1
  • I know you guys are pros and this is common sense but for newbies like me this is priceless, thanks! I actually had functions earlier in the script which are name in a PowerShell-like manner, so the for loop would expand something like export-"$entry" later. I tested it and it worked all and it work! I forgot about testing with echo though, it could've just as well gone south very fast. Thanks again!
    – Vita
    Nov 25 at 16:04
1

You should use the ${!name} syntax for variable indirection.

Bash uses the value of the variable formed from the rest of parameter as the name of the variable

So this would work:

    varnames='var1 var2 ... var8'
    for varname in $varnames
    do
        if [ "${!varname}" ]
        ...

As for portability, that will depend on the bash version in each of your environments.

3
  • variable indirection via ${!p} was in Bash 2.0 already (based on the list here), so it's probably available anywhere with Bash. But I don't think it's a thing any other shells, if that ever comes up.
    – ilkkachu
    Nov 24 at 17:59
  • Argh! I'm so conflicted bc this is quick and works dead on but I've just been told functions are for code, vars for data. I think I'll just cheat and pretend not to know about it. "Who? curly-what?! No that's not my code..." Already save it for reference in the drafts folder. Thanks!
    – Vita
    Nov 25 at 16:11
  • In the first place, programming is for getting work done. Purism is important if you want to reuse, change, maintain code, or pass it on to others.
    – db-inf
    Nov 25 at 20:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.