Question

I was trying to demonstrate the use of an associative arrary to gather counts. It is working in the while loop, but it appears to have lost all its information after the while loop. What am I doing wrong? All echo statements except for the one in the for loop have been added for debugging.

#!/bin/bash

declare -A shell_type

shells=$(cut -d: -f7 /etc/passwd)
echo "$shells"|
while read sh
do
  if [ -z "${shell_type[$sh]}" ]
  then
    shell_type[$sh]=1
  else
    let "shell_type[$sh] += 1"
  fi
  echo "$sh ${shell_type[$sh]}"
  echo "${!shell_type[*]}"
  echo "${shell_type[*]}"
done

echo "${shell_type[*]}"

for var in "${!shell_type[*]}"
do
  echo "$var count is ${shell_type[$var]}"
done
Was it helpful?

Solution

Do not pipe to your while loop, write it like this:

while read sh
do
  ...
done < <(cut -d: -f7 /etc/passwd)

If you do cmd | while then the while is in a different process. It inherits your local variables but it cannot modify them. By using input redirection, the while stays within the current process.

Btw, the first < there is for input redirection, and the <(...) after that is process substitution. You need a space in between otherwise the shell cannot separate these operators. You can read more about process substitution in man bash in the Process Substitution section.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top