I’m pretty new to bash scripting and I’m obviously missing some fairly basic understanding as I can’t work out why this script isn’t doing as I’d expect. I’ve made a simple example reproducing the problem, it is supposed to make 3 folders, with 3 folders inside, then touch a file test inside of each.
Here’s the script:
#!/bin/sh
DIR_LEVEL_1=("1" "2" "3")
for DIR_1 in ${DIR_LEVEL_1[@]}; do
mkdir $DIR_1
DIR_LEVEL_2=("$DIR_1/a" "$DIR_1/b" "$DIR_1/c")
echo $DIR_LEVEL_2
for DIR_2 in ${DIR_LEVEL2[@]}; do
mkdir $DIR_2
touch "$DIR_2/test"
done
done
The problem I was having was the it wasn’t entering the second for loop, I put in that echo and it looks like the second array isn’t being created properly as the output of the script is:
1/a
2/a
3/a
which is just the first element of the array.
running with -xv flag I get this, which shows it’s taking no notice of that nested for loop (I guess because the array didn’t get created as I wanted?)
#!/bin/sh
DIR_LEVEL_1=("1" "2" "3")
+ DIR_LEVEL_1=("1" "2" "3")
for DIR_1 in ${DIR_LEVEL_1[@]}; do
mkdir $DIR_1
DIR_LEVEL_2=("$DIR_1/a" "$DIR_1/b" "$DIR_1/c")
echo $DIR_LEVEL_2
for DIR_2 in ${DIR_LEVEL2[@]}; do
mkdir $DIR_2
touch "$DIR_2/test"
done
done
+ for DIR_1 in '${DIR_LEVEL_1[@]}'
+ mkdir 1
+ DIR_LEVEL_2=("$DIR_1/a" "$DIR_1/b" "$DIR_1/c")
+ echo 1/a
1/a
+ for DIR_1 in '${DIR_LEVEL_1[@]}'
+ mkdir 2
+ DIR_LEVEL_2=("$DIR_1/a" "$DIR_1/b" "$DIR_1/c")
+ echo 2/a
2/a
+ for DIR_1 in '${DIR_LEVEL_1[@]}'
+ mkdir 3
+ DIR_LEVEL_2=("$DIR_1/a" "$DIR_1/b" "$DIR_1/c")
+ echo 3/a
3/a
So it only creates the first level of folders
Well, the real issue with your script is that you create
DIR_LEVEL_2, but you iterate overDIR_LEVEL2. (Note the underscore difference). However, you also neglect to quote"${array[@]}", which means it will not wordsplit properly. All that aside, might I suggest you use brace expansion to make this entire thing a better experience?Edit/postscript: I notice your script above uses
#!/bin/sh, but you’ve tagged this postbash. They are not the same thing. Unless you’re certain you want to trade the greater featureset of bash for the greater portability of sh, use#!/bin/bash.