I'm trying to find and move a whole bunch of folders on a linux box.

All the folders are named the same, so I am using echo $RANDOM to provide a random number to use for a folder name.

echo $RANDOM
does indeed output a random number every time is is run. However,
find . -type d -name .AppleDouble -exec mv \'{}\' \'/raid/data/Storage/AppleDouble/`echo $RANDOM` \;
uses the same "random" number for every folder, and as a result, only moves one folder.

I think the issue is that the $RANDOM is being evaluated immediately when find begins to run. How do I escape it so the value of $RANDOM is not evaluated until the -exec option begins to run (or what is a better way to do this)?

Note: I'm on busybox, so I can't really install anything.

3 Answers 3


You are correct; you didn't quote it, so it's evaluated by the shell while building the find command line. -exec doesn't use bash normally, though, so if you single-quote it or escape the $ then it won't be expanded at all.

The solution is to invoke bash inside -exec:

find . -type d -name .AppleDouble -exec bash -c 'echo $RANDOM' \;
  • Where is the output going in that case? running it produces a lot of empty lines
    – Fake Name
    Commented Apr 27, 2012 at 7:18
  • Also, I updated the question a bit. I'm trying to use `echo $RANDOM` as one of the arguments to another command.
    – Fake Name
    Commented Apr 27, 2012 at 7:22
  • @FakeName Are you sure you are running that command exactly as given? It should work.
    – jw013
    Commented Apr 27, 2012 at 7:22
  • You said BusyBox, which makes me wonder if you're getting a usable bash under find. (If you're getting empty lines then you're getting the output but $RANDOM is unset; this I would expect of non-bash shells, in particular from BusyBox's own ash clone.) If you have a separate bash, try invoking it by full pathname so BusyBox won't be tempted to substitute its builtin ash; at least some versions of BusyBox I've seen on Android will do that substitution (annoying when I found an Android bash for my phone!)
    – geekosaur
    Commented Apr 27, 2012 at 7:23
  • @jw013 - Yes, exactly as it's given. It produces empty lines.
    – Fake Name
    Commented Apr 27, 2012 at 7:23

There are several problems with the command you're running.

mv \'{}\' \'/raid/data/Storage/AppleDouble/`echo $RANDOM`

`echo something` is equivalent to something (except when something contains some special characters, in which case the effect of the additional echo and command substitution usually makes things worse). So this is a complicated way of writing

mv \'{}\' \'/raid/data/Storage/AppleDouble/$RANDOM

The shell therefore passes three parameters to the find command for the part of the command line represented above: mv, '{}', and '/raid/data/Storage/AppleDouble/12345 where 12345 is a random value. Since the value of the RANDOM special variable is expanded by the shell before invoking find, all the commands executed by find will run with the same value. Note also that you have extra single quotes which will be parts of the file names — just drop them.

Since you want to expand $RANDOM in each invocation, you need to tell find to execute a shell which will execute mv, instead of having find execute mv directly.

find . -type d -name .AppleDouble -exec sh -c 'mv "$0" /raid/data/Storage/AppleDouble/$RANDOM' {} \;

Note that the probability of a collision in the random numbers is pretty high: $RANDOM only goes up to 215, so if you're copying more than 213 files, the probability that two files are copied to the same target is more than 50%. It is a very bad idea to use a random name in this context. Instead, use a name that is guaranteed to be distinct for every source file. One way to do this is to use a cryptographic hash of the source path:

find . -type d -name .AppleDouble -exec sh -c 'mv "$0" /raid/data/Storage/AppleDouble/$(echo "$0" | md5sum | cut -d " " -f 1)' {} \;
  • find . -type d -name .AppleDouble -exec bash -c ' echo "$0"' {} \; produces a number of empty lines, and then sh: -c: line 0: unexpected EOF while looking for matching `'' sh: -c: line 1: syntax error: unexpected end of file
    – Fake Name
    Commented Apr 30, 2012 at 7:47
  • Note that the bash on this device (it's embedded) is pretty old - [email protected]:/raid/data/Storage# bash --version GNU bash, version 3.00.16(2)-release (i486-slackware-linux-gnu) Copyright (C) 2004 Free Software Foundation, Inc.
    – Fake Name
    Commented Apr 30, 2012 at 7:48
  • Also, sh is symlinked to bash.
    – Fake Name
    Commented Apr 30, 2012 at 7:49
  • Or just increment a counter. Commented Apr 30, 2012 at 8:03

I'm not too sure what the problem actually wound up being.

I eventually gave up, and wrote an external script to pass to find's -exec, and that seems to be working.

I'm not sure why I couldn't just put the whole command in one line. It seems there are some odd bugs in the version of busybox and bash I have (this is an old version of both. It's busybox 1.1.0, which is from 2006, and bash 3.00.16 which is of a similar age (I cannot find a bash release history)).

You must log in to answer this question.

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