0

Something strange is going on with my Ubuntu 22.04 running version 5.1.16. I am having difficulty doing basic maths in a while loop.

I have a script that runs through all the MKV files in the /Instructions directory. There are thousands of them. The file was to read the titles within the files and clear them out. The code is as follows;

#!/usr/bin/sh
tot=0
spaces=0
blanks=0
text=0
testvar=3

find /Instructions -type f -name '*.mkv' | while read f; do
  ls "$f" -al
  title=$(mediainfo --Output="General;%Title% %Movie%" $f)
  echo "'$f' : "
  if [ "$title" = ' ' ]; then
    spaces=$((spaces+1))
    echo "Spaces"
echo $spaces
#    mkvpropedit "$f" --set title=''
  elif [ "$title" = '' ]; then
    blanks=$((blanks+1))
    echo "Blank"
echo $blanks
  else
    text=$((text+1))
    echo "Text"
echo $text
#    mkvpropedit "$f" --set title=''
  fi
tot=$((tot+1))
echo $tot
testvar=$((testvar+1))
echo $testvar
done
echo "Test Complete"
echo "Total : $tot"
echo "Text : $text"
echo "Spaces : $spaces"
echo "Blanks : $blanks"
echo $testvar

I commented out the active component to test the counts and it lists every file with the settings. But doesn't keep count at all at completion.

It returns this;

SNIP
'/Instructions/TestFlight310120241330.mkv' : Blank
2736
9429
'/Instructions/TestFlight310120241510.mkv' : Blank
2737
9430
'/Instructions/TestFlight010220241005.mkv' : Blank
2738
9431
'/Instructions/TestFlight010220241100.mkv' : Blank
2739
9432
Test Complete
Total : 0
Text : 0
Spaces : 0
Blanks : 0
3

I've executed it via

sh test.sh
bash test.sh

It updates the variables within the while loop but doesn't retain them on exit. Must be something stupid any ideas?

Changed variables and added in comment text. Keeps count in the while loop but loses it when out. I was expecting the variables named outside the loop to be updated whilst in the loop and retained on exit.

I used declare -i tot=0 When run in sh test.sh it was the same except Total : was blank bash test.sh was same as above.

Even tried it on Mint but it was the same.

It seems that this is a known issue with while loops running as a sub process but the solutions given for them do not cover what I am trying to do and I do not have a clue how to fix it. Is it the pipe? Should I make it a pipe to a file and feed the lines in one at a time?

9
  • Just change find … | while … do … done to while … do … done < <(find …). Commented Feb 2 at 19:30
  • After having the last second though of piping the list to a file and feeding that into the while loop. I tried it and it worked OK. So I have a solution. Is that however the best way to do this. Commented Feb 2 at 19:30
  • @Dave you can also run the rest of the code in the subprocess: find | { while do ... done; echo ... ; } Commented Feb 2 at 19:38
  • the while loop is being run in a subshell; (in bash) variable assignments in the subshell are 'lost' upon exiting subshell and returning to the parent process (ie, variable assignments are not passed 'up/back' to the parent); pmf's suggestion is the typical 'fix' (ie, the while loop is not executed in a subshell so you'll see your in-loop assignments being maintained after exiting the loop) Commented Feb 2 at 19:50
  • 1
    Shellcheck identifies several problems with the code (including the loss of variable values outside the loop). The report that it produces includes links to more information about the problems and how to fix them. It's a good idea to run Shellcheck on all new and modified shell code. Commented Feb 2 at 23:02

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.