Linux find command exception

How can I exclude all «permission denied» messages from «find»?

I am experimenting when such message arises. I need to gather all folders and files, to which it does not arise. Is it possible to direct the permission levels to the files_and_folders file? How can I hide the errors at the same time?

Great question! Unfortunately, the first three answers simply do not work on Debian Linux. Or at least my configuration of it. I needed Fatih’s solution, find /. -name ‘toBeSearched.file’ 2>/dev/null .

I found it best to exclude the /proc path using the -path option. It helps to negate the -prune option to avoid printing pruned items.

21 Answers 21

find . 2>/dev/null > files_and_folders 

This hides not just the Permission denied errors, of course, but all error messages.

If you really want to keep other possible errors, such as too many hops on a symlink, but not the permission denied ones, then you’d probably have to take a flying guess that you don’t have many files called ‘permission denied’ and try:

find . 2>&1 | grep -v 'Permission denied' > files_and_folders 

If you strictly want to filter just standard error, you can use the more elaborate construction:

find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2 

The I/O redirection on the find command is: 2>&1 > files_and_folders | . The pipe redirects standard output to the grep command and is applied first. The 2>&1 sends standard error to the same place as standard output (the pipe). The > files_and_folders sends standard output (but not standard error) to a file. The net result is that messages written to standard error are sent down the pipe and the regular output of find is written to the file. The grep filters the standard output (you can decide how selective you want it to be, and may have to change the spelling depending on locale and O/S) and the final >&2 means that the surviving error messages (written to standard output) go to standard error once more. The final redirection could be regarded as optional at the terminal, but would be a very good idea to use it in a script so that error messages appear on standard error.

There are endless variations on this theme, depending on what you want to do. This will work on any variant of Unix with any Bourne shell derivative (Bash, Korn, …) and any POSIX-compliant version of find .

Читайте также:  Linux есть ли папка

If you wish to adapt to the specific version of find you have on your system, there may be alternative options available. GNU find in particular has a myriad options not available in other versions — see the currently accepted answer for one such set of options.

Источник

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 <> \; 
rm -rf /media/disk3/Videos/Chorus/.AppleDouble 
root@doi:~# find /media/disk3 -type d -name .AppleDouble -exec rm -rf <> \; 
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=$$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.

Читайте также:  Linux изменить размер раздела ext4

Источник

How to check if find command didn’t find anything?

found something or not. If not I want to say echo ‘You don’t have files older than $DAYS days’ or something like this 😉 How I can do that in shell script?

6 Answers 6

Count the number of lines output and store it in a variable, then test it:

lines=$(find . | wc -l) if [ $lines -eq 0 ]; then . fi 

To use the find command inside an if condition, you can try this one liner :

 [[ ! -z `find 'YOUR_DIR/' -name 'something'` ]] && echo "found" || echo "not found" 
 [prompt] $ mkdir -p Dir/dir1 Dir/dir2/ Dir/dir3 [prompt] $ ls Dir/ dir1 dir2 dir3 [prompt] $ [[ ! -z `find 'Dir/' -name 'something'` ]] && echo "found" || echo "not found" not found [prompt] $ touch Dir/dir3/something [prompt] $ [[ ! -z `find 'Dir/' -name 'something'` ]] && echo "found" || echo "not found" found 

Alternatively, -n can be used instead of ! -z , for example:

[[ -n `find $dir -name $filename` ]] && echo found 
-n STRING the length of STRING is nonzero 

Exit 0 is easy with find, exit >0 is harder because that usually only happens with an error. However we can make it happen:

if find -type f -exec false <> + then echo 'nothing found' else echo 'something found' fi 

This is not correct. The question asks how to return false if it DOES NOT find anything. -exec will only run if it does find something so this would never work properly.

@deltaray: This answer returns false when files are found and true when they’re not. Simply negate the result with a ! or use the then/else as shown which is set up in a negated form.

Читайте также:  Linux or windows for games

I wanted to do this in a single line if possible, but couldn’t see a way to get find to change its exit code without causing an error.

However, with your specific requirement, the following should work:

find /directory/whatever -name '*.tar.gz' -mtime +$DAYS | grep 'tar.gz' || echo "You don't have files older than $DAYS days" 

This works by passing the output of find into a grep for the same thing, returns a failure exit code if it doesn’t find anything, or will success and echo the found lines if it does.

Everything after || will only execute if the preceding command fails.

Источник

Is there a way to specify exceptions to exclusions in the find command via Bash?

I would like to find all of the files within a directory and its subdirectories except for any settings files and anything in settings or dependency directories. For example, I want to exclude from my results entire directories like .git, .idea, and node_modules as well as files like .DS_Store and config.codekit, but I want to include .gitignore. What I want is something like the results of the following Git command, but including any untracked files and able to be easily and safely operated upon (e.g., to change permissions).

git ls-tree -r master --name-only 

Here is what I have so far and although it is rather unwieldy it seems to mostly do what I want except for leaving out .gitignore:

find . -type f -not -name ".*" -not -name config.codekit -not -path "./.*" -not -path "./node_modules/*" 

I have experimented with -prune without much success. Is there a way to specify exceptions to exclusions in the find command via Bash—to say something like exclude all the things that match this pattern EXCEPT this thing or these things? By the way, I am presently using OS X, but I also use Ubuntu and I plan to try Ubuntu on Windows when the Windows 10 Anniversary Update is generally available, so ideally I would like to have a command that works across all of those. Thank you in advance for any solutions, insights, or optimizations! Update Thanks to help from gniourf-gniourf, I have revised my command. This seems to do what I wanted:

find . -type f \( \! -name ".*" \! -name config.codekit \! -path "./.*" \! -path "./node_modules/*" -o -name .gitignore \) 

Источник

Оцените статью
Adblock
detector