2

I hope I am asking this in the right place.

I have a fairly simple bash script that I am working on, however I just started scripting bash a few days ago, and I have hit a bit of a stump.

I have seen familiar questions, but before saying read this, or duplicate, or google, understand I have tried many approaches and I am just stuck with this one roadblock.

I have the following code:

find ~/bin/ -type f ! \( -iname '*~' -o -iname '.*' \) -exec basename {} \; | sort | while read line; do
let i=i+1
command_array[$i]="$line"
echo "$i : ${command_array[$i]}"
done

echo $i
echo "array check : ${command_array[*]}"

I would like to get those variables from the loop. As I've read, it seems that somehow I need to make those variables before the pipes ? I am not sure how to accomplish this with my current code. It's a combination of: I am not sure how to restructure the code to find files to accommodate this. It looks like the foolowing is what I should be trying to acheive:

n=0
printf %s "$foo" |
while IFS= read -r line; do
n=$(($n + 1))
done
echo $n

And while I partially understand what's going on here, I am still lost as to how to start to switch what I have to something like this to get variables.

I'm not looking for someone to re-code it for me, but some tips, or hints in getting this going in the right direction would be great.

Duncubuntu
  • 130
  • 8

1 Answers1

1

The typical way to avoid the subshell when using a while read loop to consume command output is to rewrite it to redirect from process substition.

Instead of:

foo | bar | while read baz; do (( i++ )); done
echo "$i"  # Unset

use

while read baz; do (( i++ )); done <   <(foo | bar)
echo "$i"  # Works

PS: ShellCheck automatically warns about this, and links to a page with documentation on how to restructure a while loop like this.

that other guy
  • 116,971
  • 11
  • 170
  • 194