1

I'm new to bash scripting, so please bare with me as I learn here. I'm trying to audit some NetworkManger connections via a script. I'm stuck at how to get a filtered list of connection names, based on their type. More specifically, I want to have an array in the script:

declare -a FILTER
FILTER=(bond ethernet)

And then run the members of that against the command output of nmcli con show, in order to only return connections that have a type which matches a member of the FILTER array (in the example below, that would mean 'Bond0' only). I want to store the matches in RESULTS array.

Example, nmcli con show produces:

NAME        UUID            TYPE        DEVICE
Bond0       akjkajfljklfa   bond        ifbond
Wi-Fi       jkjkjjkljahjh   wifi        wlo

Whats the question:

How do I overcome the 'subshell processing resulting in an empty array at the end' problem, when processing command output?

What I've Tried:

So, I think I want to:

  1. Go line by line.
  2. Isolate fields 1 and 3 (Name and Type) from the command output.
  3. Compare field 3 for each line against the FILTER array.
  4. Store field 1 in RESULTS, if field 3 matches against a FILTER array member.

I've tried piping nmcli output into IFS= -r line; do and the passing $line to awk in various ways, then loading array -a RESULTS via a bunch of different methods such as in a loop and also using mapfile -t RESULS < <(command substitution) etc.

Whilst I can get to a point with all methods where it looks like the line used for loading matches into the RESULTS array (set -x showing it returning the correct names and loading them into the array), when I get out of whatever mechanism I have used to load the RESULTS array, it is always empty when I echo ${RESULTS[@]} with a length of 0.

I don't have all the code that I have tried, but roughly speaking, here's part of my latest fail (sorry, had to retype all this on a different machine to post this question, hence not all of it as there is a lot more in the script):

declare -a FILTER
FILTER=(bond ethernet)
declare -a RESULTS

nmcli con show | while IFS= read -r line
do
   # A bunch of if's and so forth to to filter the right things, example: #
   if [[ " ${FILTER[@]} " =~ " $(echo $line | awk {`print $3`} "]]; then
   mapfile -t RESULTS < <(nmcli con show | while IFS= read -r line; do echo $line | awk '{print $1}`)
   fi
done
echo ${RESULTS[@]}

I'm obviously doing something wrong as it relates to processing results in subshells, thinking i'm loading the array, but then stepping outside the subshell and it disappears.

Chris
  • 417
  • 3
  • 11
  • 2
    `How do I overcome the 'subshell processing resulting in an empty array at the end' problem, when processing command output?` It's well explained in [bashfaq I set variables in a loop that's in a pipeline. Why do they disappear after the loop terminates?](https://mywiki.wooledge.org/BashFAQ/024) with an extensive list of workarounds. I mean I could just copy the text and write an answer. – KamilCuk Aug 03 '20 at 12:12
  • 1
    [Bash FAQ 24 - I set variables in a loop that's in a pipeline. Why do they disappear after the loop terminates? Or, why can't I pipe data to read?](http://mywiki.wooledge.org/BashFAQ#BashFAQ.2F024.I_set_variables_in_a_loop_that.27s_in_a_pipeline._Why_do_they_disappear_after_the_loop_terminates.3F_Or.2C_why_can.27t_I_pipe_data_to_read.3F) Bookmark and save [**Bash FAQ**](http://mywiki.wooledge.org/BashFAQ) @KamilCuk - nothing wrong with writing an answer that helps. Also the double use of `nmcli con show | while ...` is another problem altogether. – David C. Rankin Aug 03 '20 at 12:15
  • Thanks gents, I'll have a read of those links. I got very suspicious of the two uses of that. I actually think I might have resolved this by getting rid of most of what I tried and just starting again using a simple RESULTS+="$(commands)" – Chris Aug 03 '20 at 12:23
  • Okay, I resolved this. I might just delete this question as the solution was basically, 'don't do entirely the wrong thing'. I had gone way, way down the wrong, very confused, rabbit hole. – Chris Aug 03 '20 at 12:37
  • Or answer you own question and do a nice write up and I'll vote for it `:)` Your question was formatted nicely. – David C. Rankin Aug 03 '20 at 13:59
  • Thanks David. I might do that, I realise now that I was sort asking the wrong question because I was already down the wrong path. I'll put up the details of the solution tomorrow, but it's nothing very impressive. I realise I had other issues to contend with as well, spaces in names, fixed width fields rather than delimited in command output, leading and trailing space being removed by `echo $var` but not `echo "$var"`...A lot of learning going on! :-) – Chris Aug 03 '20 at 14:13
  • Some helpful discussion on other things that tripped me up with respect to loading and reading elements of an array, into and out of commands: https://stackoverflow.com/questions/18135451/what-is-the-difference-between-var-var-and-var-in-the-bash-shell – Chris Aug 03 '20 at 22:28

0 Answers0