0

For the below script, list of elements in bash array is printed as expected within the loop, but when the same is printed outside the loop, its not. Can you please provide pointers on what is being missed?

pid_arr=()
pid=10
pid_arr+=($pid)
pid_arr+=(29)

ls -1 | head -2 | while read file
do
    ls -1 1>/dev/null 2>/dev/null &
    pid=$!
    echo "Pid: $pid"
    pid_arr+=("${pid}")

    echo "Within loop"
    echo "${pid_arr[@]}"
done

echo "${pid_arr[@]}"

for pid in "${pid_arr[@]}"
do
   echo "Checking pid: $pid"
done

Output for the above script

Pid: 10817
Within loop
10 29 10817
Pid: 10818
Within loop
10 29 10817 10818
10 29
Checking pid: 10
Checking pid: 29

Was expecting to see all the 4 values : 10, 29, pid1, pid2 But only 10, 29 are listed and not the pid values.

2
  • 4
    You're modifying variables in a subshell, then checking their values after returning to the main one. Use Shellcheck (as suggested by the bash tag) to get more info (among other things) on SC2031 (info): pid_arr was modified in a subshell. That change might be lost. Commented Dec 21, 2024 at 10:37
  • Thanks @pmf, that was helpful, fixed it. Commented Dec 21, 2024 at 10:59

1 Answer 1

1

Modified code based on recommendation (removed subshell usage) and working as expected.

pid_arr=()
pid=10
pid_arr+=($pid)
pid_arr+=(29)

tmp_file=abc-`date +%s`
ls -1 | head -2 > $tmp_file
while read file
do
    ls -1 1>/dev/null 2>/dev/null &
    pid=$!
    echo "Pid: $pid"
    pid_arr+=("${pid}")

    echo "Within loop"
    echo "${pid_arr[@]}"
done < $tmp_file

echo "Outside"
echo "${pid_arr[@]}"

for pid in "${pid_arr[@]}"
do
   echo "Checking pid: $pid"
done

rm $tmp_file

Output

Pid: 11122
Within loop
10 29 11122
Pid: 11123
Within loop
10 29 11122 11123
Outside
10 29 11122 11123
Checking pid: 10
Checking pid: 29
Checking pid: 11122
Checking pid: 11123
Sign up to request clarification or add additional context in comments.

3 Comments

Note: you can avoid using a temporary file with ... done < <(ls -1 | head -2).
It's time to stop using the archaic backtick syntax for command substitution, and use $(...).
It's also time to start checking your code with shellcheck.net - that would have solved your original problem and will tell you about problems in your new script that you may not be aware of yet.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.