1

I have the following bash script to make a set of directories, move to that directory, execute some actions (not shown), and move back up to the parent directory:

#!/bin/bash
if [ -e 'dump' ]; then
        rm -r dump
        mkdir dump
        D="dump/var"
else
        mkdir dump
        D="dump/var"
fi

for d in {1..24}

do
echo $D$d
mkdir $D$d/
cd $D$d
cd ..

done

When this script is executed, the result is that odd-numbered directories are made while even-numbered directories throw the error 'No such file or directory'. If I put in the option to make a parent directory, as in mkdir -p $D$d/, a nested directory results dump/var1, dump/dump/var2, dump/dump/dump/var3, et cetera.

If I remove the directory changes, cd $D$d and cd .., then the script executes without error. If I use absolute paths for the directory, as in D="/path/to/directory/dump/var", then there is 'No such file or directory' for all but the first directory created.

What is happening in the shell?

  • 2
    Run your script with bash -x scriptname to see what it is doing. – waltinator May 14 '18 at 17:22
2

Core of the issue: your script cd back to dump, not to dump/'s parent.

On first iteration:

  • You start out in dump's parent directory, where dump/ exists
  • dump/var1 is created
  • you cd into dump/var1.
  • when cd .. occurs you go back to dump/. Current working directory is dump and there's only var1 there, nothing else.

On the second iteration:

  • When you try mkdir dump/var2/ you are in dump/ and there's only var1 there. The dump/ of dump/var2 is the non-existent path. Of course it fails. Hence the error message and hence the duplicate dump/dump/var2 when you use mkdir -p flag.
  • Your script still does cd .., so before 3rd iteration current working directory changes from dump/ to dump/'s parent.

For 3rd iteration:

  • You're inside dump/'s parent directory, the path dump/ exists, hence mkdir dump/var3 won't fail.
  • cd dump/var3 occurs, then cd .., and what is the current working directory now ? dump/ , the one level above dump/var3, where you try to do mkdir dump/dump/var4, but there's only var1 and var3 there, no dump. The mkdir fails, you cd .. which goes one level above dump/, and the whole thing repeats again.

You can see this clearly when you execute our script with set -x for debugging output appended after #!/bin/bash line or by doing pwd as first command on each iteration of the script.

The way I'd recommend fixing your script is via cd into dump/ first, and then run the for loop. In other words:

cd "$D"
for i in {1..24}
do
    mkdir "$i"
    cd "$i"
    # do whatever you want inside "$i"
    cd ..
done

Among other things, I'd suggest using [ -d "dump" ] instead of -e, because that'll help you make sure the file that exists is actually the directory, although this might take extra considerations.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.