joebegborg07
joebegborg07

Reputation: 839

Bash - while inside for loop not exiting

I'm a beginner getting started with bash scripting.

I have 10 directories in current working directory dir1-dir10 + script.sh + a file called "tocopyfile".

Dir1-10 are empty. tocopyfile is a test text file to be used for the purpose of my training script.sh contains the following code:

dir=`pwd`
i="0"
for directory in `ls $dir`;do
        while [ $i -le 10 ]
        do
        cp tocopyfile $directory/file$i &
        i=$[$i+1]
        done
done

The script should copy 10 copies of the file "tocopyfile" to every dir (dir1-10) in the naming convention file#. The problem is that ones the script is exists after the first directory without executing the while loop to the remaining remaining dirs.

Can someone explain what I'm doing wrong please?

Help is greatly appreciated.

Upvotes: 1

Views: 1746

Answers (2)

bishop
bishop

Reputation: 39364

You need to initialize $i inside the for loop, such that $i == 0 upon each iteration of your while:

dir=`pwd`
for directory in `ls $dir`;do
    i="0" # <===== notice the change here
    while [ $i -le 10 ]
    do
    cp tocopyfile $directory/file$i &
    i=$[$i+1]
    done
done

Other things you might want to change:

  1. Double-quote all your variables (in the event they have spaces in them).
  2. Use $() instead of the long-deprecated back-tick syntax.
  3. Use $(()) instead of the deprecated $[] syntax.
  4. Tidy up your indentation.

Upvotes: 1

chepner
chepner

Reputation: 530970

The immediate issue is that you need to reset the value of i for each iteration of the outer loop.

for directory in `ls $dir`; do  # No! but more on that in a moment
    i=0
    while [ $i -le 10 ]

There are a few other issues with your code.

  1. dir=$(pwd) is almost always pointless; bash already provides a variable PWD containing the name of the current working directory. You don't actually need this, though; you can simply use ./*/ to expand to a list of directories in the current working directory.

  2. Never use the output of ls in a script.

  3. $[...] is obsolete syntax; use $((...)) instead.


Cleaning your code up a bit, we get

for directory in ./*/; do
    i=0
    while [ "$i" -le 10 ]; do
        cp tocopyfile "$directory/file$i" &
        i=$((i+1))
    done
done

Upvotes: 2

Related Questions