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 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 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.

Not the answer you're looking for? Browse other questions tagged .