2

I have the following section in my bash script:

# Move to script's source directory (in case it's being called from somewhere else)
cd $(dirname "${BASH_SOURCE[0]}")
# Save script's source directory
pwd=$(pwd)
# If it's not already ~/.cfg
if [ ! "$pwd" -ef ~/.cfg ]; then
        echo "Renaming directory"
        # Move up one level (since you can't rename directory while in it)
        cd ..
        # And rename it
        mv "$pwd" ~/.cfg
fi

The script is a setup script for a git repository, to be run right after cloning it. The idea is to move the entire repository to ~/.cfg. However, I get an error saying

mv: cannot move '/home/user/config' to '/home/user/.cfg': Permission denied

Permissions are set appropriately and invoking the same mv from the command line works without problems.

I'm guessing the problem is that I'm renaming a directory, while the script inside it is still running, and simply moving out of it via cd (as in the above snippet) isn't enough. Is there a way to work around that?


In the end it turned out I could do something simpler than the accepted answer below, though in the same spirit of running the removal at the very end.

I simply changed the mv command to a cp -r, then added a rm -rf "$pwd" at the very end of the script. Apparently rm's -f flag ignores the fact that the script is running. The script now works as intended.

1
  • The easiest workaround I can think of is to put the script in ~/bin/ and add that directory to your path. Have you considered that, and if so, why is that not an easy, workable solution?
    – Jim L.
    Commented Feb 16, 2019 at 1:07

1 Answer 1

1

I suggest having two scripts: One that moves everything except the first script, and one that just moves the first script and removes the folder.

At the end of the first script, exec the second script from the new location. That will replace the process and close the handle on the first script. That second script can then move the first script and remove the now-empty original folder.

Something like

# Move to script's source directory (in case it's being called from somewhere else)
cd $(dirname "${BASH_SOURCE[0]}")
# Save script's source directory
pwd=$(pwd)
# If it's not already ~/.cfg
if [ ! "$pwd" -ef ~/.cfg ]; then
        echo "Renaming directory"
        # Move up one level (since you can't rename directory while in it)
        cd ..
        # And rename it
        for i in "$pwd"; do
                if [ "$i" != "${BASH_SOURCE[0]}" ]; then mv "$i" ~/.cfg; fi
        done
        exec ~/.cfg/script2.sh "${BASH_SOURCE[0]}"
fi

Then script 2:

#!/bin/bash
# first arg is path to script you call it from.
base=basename "$1"
dir=dirname "$1"
mv "$1" ~/.cfg/$base
rmdir $dir
1
  • Oh I like that, that should work fine. Commented Feb 16, 2019 at 22:21

You must log in to answer this question.

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