Bash – Can multiple mv commands be run in the same directory (race condition)

bashmvshell

I'm moving a large number of files (400K+) from one directory to another and I have the following script to do so (too many files for the mv command to work directly):

for file in *;
do
    mv $file ..
done

If I run this script twice (or more) at the same time, will there be a race condition when/if the mv commands are trying to access the same file?

I've looked around on the web but haven't found any definite answer. Thanks!

Best Answer

There is indeed a race condition (one that wouldn't cause harm, though).

The * is expanded on entry to the loop. If you run a second instance of this script simultaneously then it will probably do nothing because all files it tries to move have already been moved. If no files are created in the source directory during the moving operation then the error messages should be your biggest problem.

But in general this structure is a very bad idea. * expands to a sorted list. AFAIK it is not possible to deactivate that. Obviously, the sorting alone is a nightmare with 400K files. See man bash, section "Pathname Expansion":

After word splitting, unless the -f option has been set, bash scans each word for the characters *, ?, and [. If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of file names matching the pattern.

Furthermore you should not run one mv instance per file as you can move several files at once.

This is a better solution (in the GNU world):

find . -mindepth 1 -maxdepth 1 -exec mv --target-directory=DIRECTORY {} +