Visit Our UNIX and Linux User Community


Using "find" and "-exec rm" ... Just no luck :(


 
Thread Tools Search this Thread
Top Forums UNIX for Dummies Questions & Answers Using "find" and "-exec rm" ... Just no luck :(
# 22  
Old 08-29-2009
jilagre, it may be a shorter list if you nominate those unix and Linux Operating Systems of which you have personal experience and you can prove that it works. I don't recall a post nominating one.
Solaris 10 and HP-UX 11 onwards are already definites.

There was a reason that I deduced that "{}" was needed - it has happened to me before.

My interpretation of "man find" is that the filename list resulting from the "find" is made available to the exec command as {} . It can appear on the exec line multiple times which can be handy for renaming files. The debate starts when the filename contains space characters. I maintain that many versions of unix or Linux through the ages require "{}" , and I use that syntax out of habit.

I haven't forgotten that the "find ... -exec" was a quick way to crash System V release III with "too many forks". That was when I started using alternative techniques, but I do still find some use for "find ... -exec".

There was somebody posting earlier who had Tru64 (aka DEC unix). I can't be sure whether it worked on that one beacause all my library scripts contain "{}".

Other posters may wish to try the commands on their Operating System and contribute to this debate. Please be careful with "rm" and use "echo" where possible just in case {} does not do what you expect (like what happened to the original poster in this thread).
# 23  
Old 08-29-2009
I would have to to agree in general with Jlliagre, and I believe that methyl's observations show a possible behavior but that the interpretation of why this happens is incorrect.

The {} in find is a substitution for the found string, with or without spaces. It is should not require quoting, and should be passed directly as a single element to the array of arguments for the exec() irrespective of how many times it occurs in the command.

I would also agree that any version of find that requires quotes to handle multi-word strings is very odd, given that the executed command is not interpreted by the shell but just used as a substitution internally in the find command prior to exec() of the specified command.

That being said however the shell being used could easily affect the outcome. If the shell interprets the {} and makes a substitution or expansion prior to running the find command then all bets are off. I can't think of an example off hand, but similar things happen with the '!' character. Using ksh I could use a veritas command with a disk layout like:
Code:
disk1 disk2 !disk3 !disk4

However if I do the same thing in bash, it would have to be:
Code:
disk1 disk2 \!disk3 \!disk4

because the '!' would be interpreted as history expansion.

In summary then: depending on the the shell being used, the quotes may protect from expansion by the parent shell in which find is running but they should not have any effect in preserving multi-word filenames.

---------- Post updated at 08:58 PM ---------- Previous update was at 08:56 PM ----------

For reference, the quotes are not needed on Ubuntu for any of the well known shells. I can only conclude that Dean Rotherham has something non standard because his observations of the behavior of Ubuntu are not correct ( nor would they be correct for any Linux based OS I know of, past or present ).
# 24  
Old 08-29-2009
Good explanation Reborg.

Slightly off topic but the behaviour of quotes in this context is interesting. In most cases we use quotes to ensure that "find" receives parameters without interference from the shell.
Spot the anomaly in HP-UX 11.11 (which does not have the unquoted {} problem).

Code:
touch 'a b'
find . -type f -name 'a b' -exec echo {} {} \;
./a b ./a b

find . -name 'a b' -exec echo '{}' \;
./a b

find . -name 'a b' -exec echo '{} {}' \;
{} {}

find . -name 'a b' -exec echo '{}' '{}' \;
./a b ./a b


Afterthought with respect to the original post:
Using "rm -f" rather than just "rm" could well hide an error message saying "non-existent" or a "Usage" error.

Last edited by methyl; 08-29-2009 at 05:43 PM.. Reason: Afterthought and various typos
# 25  
Old 08-29-2009
Quote:
Originally Posted by methyl
jilagre, it may be a shorter list if you nominate those unix and Linux Operating Systems of which you have personal experience and you can prove that it works. I don't recall a post nominating one.
I have some experience with quite a lot of Unix and Linux OSes, starting with version 7 in the early eighties, then various flavors of BSD based OSes, then a bunch of System V based OSes, not to mention Minix and most of the mainsteam Gnu/Linux based distributions. I do not recall any of these requiring these black magic quotes and of course none of the ones I currently use/work with show what you claim is possible. This includes Solaris 8, 9, 10, Express, OpenSolaris, Ubuntu, Red-Hat, Debian, Suse.

In any case, I'm afraid you are missing my point. Using these quotes cannot have any effect regardless of the OS. The simple reason is they aren't passed to the find command by the shell. This is by design. As the find command is the one that does the file expansion, the presence of a space in the path cannot be altered by something the find command cannot be aware of.
# 26  
Old 08-29-2009
MySQL

Quote:
Originally Posted by methyl
Good explanation Reborg.

Slightly off topic but the behaviour of quotes in this context is interesting. In most cases we use quotes to ensure that "find" receives parameters without interference from the shell.
Spot the anomaly in HP-UX 11.11 (which does not have the unquoted {} problem).

Code:
touch 'a b'
find . -type f -name 'a b' -exec echo {} {} \;
./a b ./a b

find . -name 'a b' -exec echo '{}' \;
./a b

find . -name 'a b' -exec echo '{} {}' \;
{} {}

find . -name 'a b' -exec echo '{}' '{}' \;
./a b ./a b

Afterthought with respect to the original post:
Using "rm -f" rather than just "rm" could well hide an error message saying "non-existent" or a "Usage" error.
I don't find this unusual at all, it is exactly what I would expect. {} is being passed as an argument in most cases and find behaves correctly by using it as a substitution. In effect the quotes do nothing at all in this case because they are stripped by the shell and {} a valid argument for find. In the case where '{} {}' is used when the quotes are stripped the argument is {} {} ( one argument ) and find does not interpret this because "{} {}" has no special meaning to find, this gets passed directly to echo.

Consider this code fragment which illustrates what happens:

Code:
#!/bin/ksh
#
#  find.sh
#

i=1
while [[ $# -gt 0 ]] ; do

    case $1 in
        {} )
            echo "arg $i : Found special string {}"
            shift
            ;;
        * )
            echo "arg $i is : $1"
            shift
            ;;
    esac
    (( i = i + 1 ))
done


Code:
./find.sh {} {} "{}" '{}' '{} {}' "{} {}"
arg 1 : Found special string {}
arg 2 : Found special string {}
arg 3 : Found special string {}
arg 4 : Found special string {}
arg 5 is : {} {}
arg 6 is : {} {}

The point is that unless {} actually has a meaning in the shell, then the quotes are never needed. If the quotes are needed it is not to preserve spaces in the filename, it is to prevent shell interpretation.
# 27  
Old 08-29-2009
Similar background, but I may have 10 years head start largely due to time spent on VME and VMS.

Omg! Minix (nostalgic moment).
Remember OS/9 (not the MAC one)?

Notwithstanding our combined experience we will both have seen anomalous behaviour in Operating Systems.

I cannot believe that I am the only person to have encountered problems with unix commands dealing with space characters in filenames.
The question still remains: Why have I seen the "{}" problem before?

I am exploring Reborg's ideas which imply that some older shells were eating the {}. If proven, this would explain it. I don't have access to the source code to the various editions of "find" - unlike when I was working on enhancements to RSX.


Sorry Reborg, my example was pedantic and addressed to those who quote the POSIX definition of the expected behaviour of a command rather than to those of us who know how the command behaves in a shell enviroment if we use that command correctly.

As we all know from the roots of unix, if all else fails and the command does not do what you want - write your own.



Btw. jlliagre is cool and I am enjoying this debate.

Last edited by methyl; 08-29-2009 at 07:44 PM.. Reason: Remove "post updated" because it looks awful
# 28  
Old 08-29-2009
Quote:
Originally Posted by methyl
Btw. jlliagre is cool and I am enjoying this debate.
Me too, I'm running through some old shells to see if I can find one that treats an empty {} as special.
 

Previous Thread | Next Thread
Test Your Knowledge in Computers #919
Difficulty: Medium
The Unix epoch is the time 00:00:00 EST on 1 January 1970.
True or False?

9 More Discussions You Might Find Interesting

1. AIX

Apache 2.4 directory cannot display "Last modified" "Size" "Description"

Hi 2 all, i have had AIX 7.2 :/# /usr/IBMAHS/bin/apachectl -v Server version: Apache/2.4.12 (Unix) Server built: May 25 2015 04:58:27 :/#:/# /usr/IBMAHS/bin/apachectl -M Loaded Modules: core_module (static) so_module (static) http_module (static) mpm_worker_module (static) ... (3 Replies)
Discussion started by: penchev
3 Replies

2. Shell Programming and Scripting

Bash script - Print an ascii file using specific font "Latin Modern Mono 12" "regular" "9"

Hello. System : opensuse leap 42.3 I have a bash script that build a text file. I would like the last command doing : print_cmd -o page-left=43 -o page-right=22 -o page-top=28 -o page-bottom=43 -o font=LatinModernMono12:regular:9 some_file.txt where : print_cmd ::= some printing... (1 Reply)
Discussion started by: jcdole
1 Replies

3. Shell Programming and Scripting

find . -path "*_nobackup*" -prune -iname "*.PDF" \( ! -name "*_nobackup.*" \)

These three finds worked as expected: $ find . -iname "*.PDF" $ find . -iname "*.PDF" \( ! -name "*_nobackup.*" \) $ find . -path "*_nobackup*" -prune -iname "*.PDF" They all returned the match: ./folder/file.pdf :b: This find returned no matches: $ find . -path "*_nobackup*" -prune... (3 Replies)
Discussion started by: wolfv
3 Replies

4. UNIX for Dummies Questions & Answers

Using "mailx" command to read "to" and "cc" email addreses from input file

How to use "mailx" command to do e-mail reading the input file containing email address, where column 1 has name and column 2 containing “To” e-mail address and column 3 contains “cc” e-mail address to include with same email. Sample input file, email.txt Below is an sample code where... (2 Replies)
Discussion started by: asjaiswal
2 Replies

5. Shell Programming and Scripting

Find lines with "A" then change "E" to "X" same line

I have a bunch of random character lines like ABCEDFG. I want to find all lines with "A" and then change any "E" to "X" in the same line. ALL lines with "A" will have an "X" somewhere in it. I have tried sed awk and vi editor. I get close, not quite there. I know someone has already solved this... (10 Replies)
Discussion started by: nightwatchrenba
10 Replies

6. Shell Programming and Scripting

awk command to replace ";" with "|" and ""|" at diferent places in line of file

Hi, I have line in input file as below: 3G_CENTRAL;INDONESIA_(M)_TELKOMSEL;SPECIAL_WORLD_GRP_7_FA_2_TELKOMSEL My expected output for line in the file must be : "1-Radon1-cMOC_deg"|"LDIndex"|"3G_CENTRAL|INDONESIA_(M)_TELKOMSEL"|LAST|"SPECIAL_WORLD_GRP_7_FA_2_TELKOMSEL" Can someone... (7 Replies)
Discussion started by: shis100
7 Replies

7. Shell Programming and Scripting

cat $como_file | awk /^~/'{print $1","$2","$3","$4}' | sed -e 's/~//g'

hi All, cat file_name | awk /^~/'{print $1","$2","$3","$4}' | sed -e 's/~//g' Can this be done by using sed or awk alone (4 Replies)
Discussion started by: harshakusam
4 Replies

8. UNIX for Dummies Questions & Answers

Explain the line "mn_code=`env|grep "..mn"|awk -F"=" '{print $2}'`"

Hi Friends, Can any of you explain me about the below line of code? mn_code=`env|grep "..mn"|awk -F"=" '{print $2}'` Im not able to understand, what exactly it is doing :confused: Any help would be useful for me. Lokesha (4 Replies)
Discussion started by: Lokesha
4 Replies

9. UNIX for Dummies Questions & Answers

No utpmx entry: you must exec "login" from lowest level "shell"

Hi I have installed solaris 10 on an intel machine. Logged in as root. In CDE, i open terminal session, type login alex (normal user account) and password and i get this message No utpmx entry: you must exec "login" from lowest level "shell" :confused: What i want is: open various... (0 Replies)
Discussion started by: peterpan
0 Replies

Featured Tech Videos