2

I'm not an experienced programmer. So maybe it's obvious for you why the break command in this script does not terminate the loop, but I can't see what is causing the problem. I want to use the script to mount a VHD file to the first empty NBD "slot" (which is assumed when it's size is zero, I took this idea from another thread on this site).

function vhdmount() {
 workfile="$1"
 if test -e "$workfile"
 then
  workname=${workfile##*'/'}
  echo "$(tput setaf 3)*** ${workfile}: ***$(tput setaf 7)"
  for (( i=0; i<16; i++ ))
  do (
   if test -e /sys/class/block/nbd${i}/size
   then
    usedornot=$( cat /sys/class/block/nbd${i}/size )
    if (( "$usedornot" == 0 ))
    then
     firstfree=$i
     break
    fi
   else
    firstfree=$i
    break
   fi
  ); done
  sudo modprobe nbd
  sudo qemu-nbd -c /dev/nbd${firstfree} "$workfile"
  sudo mkdir "/media/myusername/${workname//.vhd/.nbd${firstfree}}/"
  sudo mount /dev/nbd${firstfree}p1 "/media/myusername/${workname//.vhd/.nbd${firstfree}}/"
  echo "$(tput setaf 3)    successfully mounted.$(tput setaf 7)"
 fi
}

vhdmount "$1"

Maybe there are other errors as well. I'm always terminating the shell when it asks for the password, because I can tell from the 16 messages telling me that a break command is only useful in a for loop that the break command did not work. By the way, what a useless error message is that?!

2
  • 2
    Is there any reason you are using a subshell () after the for ((...)) do? Quote: Since the list is executed in a subshell, variable assignments do not remain in effect after the subshell completes. The error message is actually quite useful, as it gives a clue that there was a break outside of a loop (since it is in a subshell). Commented Jun 24, 2024 at 10:20
  • I see, that's a subshell problem. I wasn't aware of that! I'm a newbie, as I wrote. Removed it and it's ok now. Thanks a lot!
    – Shakesbeer
    Commented Jun 24, 2024 at 10:27

1 Answer 1

4

The error is due to the use of a subshell inside of a for. The GNU Bash Reference Manual states:

Since the list is executed in a subshell, variable assignments do not remain in effect after the subshell completes.

The error message is actually quite useful, as it gives a clue that there was a break outside of a loop (since it is in a subshell).

As a general recommendation, you can use the shellcheck utility or https://www.shellcheck.net/ to check your code for some common errors. For the provided code, it gives several warnings about the firstfree variable being modified inside of a subshell, as well as warnings about breaks.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.