-1

hope someone can help me with some very basic stuff. I'm currently writing a bashscript that is supposed to read some filepaths and to write it into an array but when I try to output the array afterwards it seems it is empty. Can someone tell me why?

#!bin/bash

counter=0;
find /home/ftpuser/TTT -type f | while read line;
   do
      origin[counter]=$line;
      counter=${$counter + 1};
      echo $counter
   done

for(int i=0;i<${origin[@]})
do
   echo ${origin[$i]};
done

The first echo outputs 1-124 but the second one absolutely nothing.

  • 2
    Your `while` loop operates in a subshell. Any variable set in that subshell will disappear after the subshell exits. See an excellent discussion of this issue, see: [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/024) – John1024 May 13 '17 at 22:19
  • BTW, you should use `-print0` to NUL-delimit your results from `find`, and `while IFS= read -r -d '' line` to read them. Otherwise, someone running `dir=/home/ftpuser/TTT/mydir/$'\n'/etc; mkdir -p "$dir" && touch "$dir"/passwd` is going to cause *interesting* results when your script runs: The literal newline present in that filename can't be passed out of `find` literally because it would be parsed as a delimiter. – Charles Duffy May 14 '17 at 00:06

2 Answers2

0

This has to be a duplicate but I couldn't find one on a quick search.

The right hand side of the pipe runs in a subshell that exits as soon as the loop does, taking its variables with it. Use process substitution instead:

while read line; do
...
done < <(find /home/ftpuser/TTT -type f)

Also, if you're running Bash 4+, you can read lines into an array all at once with mapfile (also known as readarray) instead of coding your own loop:

mapfile -t origin < <(find /home/ftpuser/TTT -type f)
Mark Reed
  • 91,912
  • 16
  • 138
  • 175
  • Ok, thanks a lot for the help but there is one small think i am wondering about. It didnt work for me when leaving the braces around the find command. Why do i need it? Wouldnt the shell execute the whole command anyway? – Flo Herick May 14 '17 at 20:20
  • What braces? I don't understand what you tried that didn't work. – Mark Reed May 14 '17 at 22:48
0

You aren't using any feature of find that can't be handled in pure shell:

shopt -s nullglob globstar
for f in /home/ftpuser/TTT/**/*; do
  [[ -f $f ]] || continue
  origin+=("$f")
done

for f in "${origin[@]}"; do
  echo "$f"
done
chepner
  • 497,756
  • 71
  • 530
  • 681