Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

Can any one tell me why the following command won't run :

find ./assign/*.c -exec cp ./assign2 {} \;

and what's the difference when i do the following(which actually runs):

find ./assign -type f -name *.c  -exec cp {} ./assign2 \;
share|improve this question
add comment

2 Answers 2

find ./assign/*.c -exec cp ./assign2 {} \;

The wildcard (*) is expanded by the shell before even find is executed. Say there are two files, source1.c and source2.c in the assign directory, then the above is equivalent to

find ./assign/source1.c ./assign/source2.c -exec cp ./assign2 {} \;

This is by all means valid, and means that you only want to do something with these particular files. For example, you could write

find ./assign/*.c -name '*2*'

and the result would be roughly equivalent to ls ./assign/*.c | grep 2 or ls ./assign/*2*.c.

Note that if you don't want the shell to expand the wildcards, you need to put them in quotes:

find "./assign/*.c"

However, that will fail, as find treats the path name literally (without any wildcard expansion), so it looks literally for a file called *.c (yes, that is a valid filename).

As for the second part of your first expression (exec cp ./assign2 {} \;). Obviously, there is a typo, since the cp command tries to copy the assign2 directory to the second argument. Given that you have files source1.c and source2.c in the assign directory, the result of your command will be equivalent to

cp assign2/ ./assign/source1.c
cp assign2/ ./assign/source2.c

Which is probably not what you intended (also, it will fail, because you cannot copy a directory to a filename).

Now, for the second expression, because there is a problem here as well:

find ./assign -type f -name *.c  -exec cp {} ./assign2 \;

This will work only if there are no files with the .c extension in the current directory. Otherwise, shell will expand the *.c. Say, you have the following files:

./master.c
./assign/source1.c
./assign/source2.c

The above command line will be first expanded by shell to

find ./assign -type f -name master.c -exec cp {} ./assign2 \;

That will fail, because there is no file master.c in the assign/ directory. Instead, use

find ./assign -type f -name "*.c" -exec cp {} ./assign2 \;

In any case, unless you have a complex directory structure under ./assign or directories that end in .c, I'd rather just

cp ./assign/*.c ./assign2
share|improve this answer
add comment

For "find" you need to specify, in order:

  • where to search (./assign)
  • type of document (-type f aka file), but this is optional
  • name of document (-name *.c aka every file with extension = .c), and this is not optional

Then, you are telling "find" that, after the search, it has to run a specific command (-exec) and syntax for "cp" is correct on both commands you are issuing, but since the syntax for "find" in the first one is incorrect, the first one won't run.

BTW, I don't think either that, after finding all .c files, does make any sense to copy the directory ./assign2 to the actual finding ({}), but rather the other way around. That is, IMHO, that even if the syntax is correct, the "cp" command in the first line doesn't do anything.

share|improve this answer
    
Of course -name is optional. Type find /home and see what it does. –  January Sep 5 '12 at 7:22
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.