Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

find command in bash script resulting in "No such file or directory" error only for directories?

UPDATE 2014-03-21

So I realized I wasn't as efficient as I could be, as all the disks that I needed to "scrub" were under /media and named "disk1, disk2,disk3, etc." Here's the final script:

DIRTY_DIR="/media/disk*" 
find $DIRTY_DIR -depth -type d -name .AppleDouble -exec rm -rf {} \;
find $DIRTY_DIR -depth -type d -name .AppleDB -exec rm -rf {} \;
find $DIRTY_DIR -depth -type d -name .AppleDesktop -exec rm -rf {} \;
find $DIRTY_DIR -type f -name ".*DS_Store" -exec rm -f {} \;
find $DIRTY_DIR -type f -name ".Thumbs.db" -exec rm -f {} \; #  I know, I know, this is a Windows file.

Next will probably to just clean up the code even more, and add features like logging and reporting results (through e-mail or otherwise); excluding system and directories; and allowing people to customize the list of files/directories.

Thanks for all the help!

UPDATE

Before I incorporated the helpful suggestions provided by everyone, I performed some tests, the results of which were very interesting (see below).

As a test, I ran this command:

root@doi:~# find /media/disk3 -type d -name .AppleDouble -exec echo rm -rf {} \;

The results (which is what I expected):

rm -rf /media/disk3/Videos/Chorus/.AppleDouble

However, when I ran the actual command (without echo):

root@doi:~# find /media/disk3 -type d -name .AppleDouble -exec rm -rf {} \;

I received the same "error" output:

find: `/media/disk3/Videos/Chorus/.AppleDouble': No such file or directory

I put "error" in quotes because obviously the folder was removed, as verified by immediately running:

root@doi:~# find /media/disk3 -type d -name .AppleDouble -exec rm -rf {} \;
root@doi:~# 

It seems like the find command stored the original results, acted on it by deleting the directory, but then tried to delete it again? Or is the -f option of rm, which is supposed to be for ignoring nonexistent files and arguments, is ignored? I note that when I run tests with the rm command alone without the find command, everything worked as expected. Thus, directly running rm -rf ... \nonexistent_directory, no errors were returned even though the "non_existent_directory" was not there, and directly running rm -r \nonexistent_directory provided the expected:

rm: cannot remove 'non_existent_directory': No such file or directory

Should I use the -delete option instead of the -exec rm ... option? I had wanted to make the script as broadly applicable as possible for systems that didn't have -delete option for find.

Lastly, I don't presume it matters if /media/disk1, /media/disk2, ... are combined in an AUFS filesystem under /media/storage as the find command is operating on the individual disks themselves? Thanks for all the help so far, guys. I'll publish the script when I'm done.

ORIGINAL POST

I'm writing a bash script to delete a few OS X remnants on my Lubuntu file shares. However, when executing this:

...
BASE_DIR="/media/disk" # I have 4 disks: disk1, disk2, ...   
COUNTER=1

while [ $COUNTER -lt 5 ]; do      # Iterate through disk1, disk2, ...
   DIRTY_DIR=${BASE_DIR}$COUNTER     # Look under the current disk counter /media/disk1, /media/disk2, ...
   find $DIRTY_DIR -name \.AppleDouble -exec rm -rf {} \;    # Delete all .AppleDouble directories
   find $DIRTY_DIR -name ".*DS_Store" -exec rm -rf {} \;     # Delete all .DS_Store and ._.DS_Store files
   COUNTER=$(($COUNTER+1))
done
...

I see the following output:

find: /media/disk1/Pictures/.AppleDouble: No such file or directory

Before I added the -exec rm ... portion the script found the /media/disk1/Pictures/.AppleDouble directory. The script works properly for removing DS_Store files, but what am I missing for the find command for directories?

I'm afraid to screw too much with the -exec portion as I don't want to obliterate directories in error.

like image 236
El Jorge Avatar asked Mar 17 '14 18:03

El Jorge


People also ask

How fix bash No such file or directory?

Use the dos2unix Command to Solve the bash: No such file or directory Error in Linux Bash. Unix operating systems use line feed ( "\n" ) as the end of the line, but Windows operating systems use carriage return and line feed ( "\r\n" ). So if you try to execute a code written in Windows on Linux, you may get this error ...

How do you deal with no such file or directory?

The error "FileNotFoundError: [Errno 2] No such file or directory" is telling you that there is no file of that name in the working directory. So, try using the exact, or absolute path. In the above code, all of the information needed to locate the file is contained in the path string - absolute path.

Why is it showing no such file or directory?

log No such file or directory” the problem is most likely on the client side. In most cases, this simply indicates that the file or folder specified was a top-level item selected in the backup schedule and it did not exist at the time the backup ran.

What is the Find command in bash?

The Bash find Command 101 The find command allows you to define those criteria to narrow down the exact file(s) you'd like to find. The find command finds or searches also for symbolic links (symlink). A symbolic link is a Linux shortcut file that points to another file or a folder on your computer.


2 Answers

tl;dr - Pass -prune if you're deleting directories using find.

For anyone else who stumbles on this question. Running an example like this

find /media/disk3 -type d -name .AppleDouble -exec rm -rf {} \;

results in an error like

rm: cannot remove 'non_existent_directory': No such file or directory

When finding and deleting directories with find, you'll often encounter this error because find stores the directory to process subdirectories, then deletes it with exec, then tries to traverse the subdirectories which no longer exist.

You can either pass -maxdepth 0 or -prune to prevent this issue. Like so:

find /media/disk3 -type d -name .AppleDouble -prune -exec rm -rf {} \;

Now it deletes the directories without any errors. Hurray! :)

like image 179
Cody A. Ray Avatar answered Sep 23 '22 23:09

Cody A. Ray


You don't need to escape DOT in shell glob as this is not regex. So use .AppleDouble instead of \.AppleDouble:

find $DIRTY_DIR -name .AppleDouble -exec rm -rf '{}' \;

PS: I don't see anywhere $COUNTER being incremented in your script.

like image 24
anubhava Avatar answered Sep 21 '22 23:09

anubhava