1

The purpose is to copy files generated in last 2 hours. Here is the small script:

a=`find . -mmin -120 -ls` 
cp $a /tmp/

echo $a 
401 1 drwxr-x--- 2 oracle oinstall 1024 Mar 26 11:00 . 61 
5953 -rw-r----- 1 oracle oinstall 6095360 Mar 26 11:00 ./file1
5953 -rw-r----- 1 oracle oinstall 6095360 Mar 26 11:00 ./file2

I get the following error:

cp: invalid option -- 'w'
Try `cp --help' for more information.

How can I fix the script ?

ErAB
  • 855
  • 4
  • 15
  • 30
  • 1
    try `cp -- $a /tmp`. It seems that some of your files are messing with the cp options. – Aif Mar 26 '15 at 15:11

3 Answers3

3

the -ls is giving you ls style output. Try dropping that and you should just get the relative path to the file which should be more like what you want. Or see Biffen's comment on your question, that seems like the approach I would have taken.

Jonathan Adelson
  • 3,275
  • 5
  • 29
  • 39
3

One problem is that -ls will print a lot of things beside the filenames, and they will be passed to cp and cp will be confused. So the first thing to do is to stop using -ls. (In the future you can use set -x to see what gets executed, it should help you debug this type of problem.)

Another problem is that the output of find can contain spaces and other things (imagine a file named $(rm -r *)) that can't simply be passed as arguments to cp.

I see three different solutions:

  1. Use a single find command with -exec:

    find . -mmin -120 -exec cp {} /tmp/ \;
    
  2. Use xargs:

    find . -mmin -120 -print0 | xargs -0 cp -t /tmp/
    

    (Note the use of -t with cp to account for the swapped arguments.

  3. Iterate over the output of find:

    while IFS='' read -r -d '' file
    do
      cp "${file}" /tmp/
    done < <( find . -mmin -120 -print0 )
    

(Caveat: I haven't tested any of the above.)

Community
  • 1
  • 1
Biffen
  • 6,249
  • 6
  • 28
  • 36
  • i am not quite sure 2 and 3 will be able to handle corner cases successfully but 1 will. it's really subtle for posix to allow `\n` as a part of name. – Jason Hu Mar 26 '15 at 15:31
  • @HuStmpHrrr Any cases in particular? Both 2 and 3 should handle `\n` just fine. (Just tested 2 and it worked great.) – Biffen Mar 26 '15 at 15:33
  • my bad. it seems they are perfect. – Jason Hu Mar 26 '15 at 15:37
0

All you have to do is to extract only the filenames. So, change the find command to the following:

    a=`find . -mmin  -120 -type f`
    cp $a /tmp/

Above find command only captures the files and finds only files whose where modified in last 120 mins. Or do it with single find command like below:

find . -mmin -120 -type f -exec cp '{}' /tmp/ \;
rakib_
  • 136,911
  • 4
  • 20
  • 26
  • The first one will not work with files whose names contain special characters, e.g. spaces or asterisks. – Biffen Mar 26 '15 at 15:40