Operating System - HP-UX
1838891 Members
2165 Online
110131 Solutions
New Discussion

Using * doesn't copy all files.

 
SOLVED
Go to solution
Jonathan Taylor_3
Occasional Advisor

Using * doesn't copy all files.

I'm about to rip out my hair on this one. I have a large number of files that I must copy multiple times and they all start with . (i.e. .profile) but when I type:

cp /home/user/*

I get:
cp: cannot access /home/user/*: No such file or directory

Even though I know the files are there. I have tried substituting *.* and .* to no avail, they both give the same message. Is there any way to pick up all of these files using a single command?
9 REPLIES 9
Jeff_Traigle
Honored Contributor
Solution

Re: Using * doesn't copy all files.

Safest way to do this is:

cp /home/user/.[A-Za-z]* destination_path

If you only put .*, it will try to grab . and .. also and give you error s about needing the -R option. Of course, if you have directory names that are hidden (named .something) that you want copied too, you need the -R option anyway.
--
Jeff Traigle
Jonathan Taylor_3
Occasional Advisor

Re: Using * doesn't copy all files.

Thanks, that took care of it.
Bill Hassell
Honored Contributor

Re: Using * doesn't copy all files.

It's important to understand that filenames that start with a . (period) are "hidden" files as far as Unix shells are concerned. So the * all by itself will *not* match filenames like .profile and .exrc because they are hidden. You will see this in the ls command but you can override this with the ls -a option (see: man ls).

Now be VERY careful about using various incantations of the . and the * as these filename matching options can have unexpected consequences. Whenever I am in doubt about using filename matching characters, I will put the word "echo" in front of the command to see what will actually happen. Something like this:

echo cp /home/user/*.

This is especially important if you are removing files (rm). You might be tempted to use .* which will match filenames that start with a dot followed by zero or more characters. This is very important: there are two files that sysadmins often forget about: these are . and .. which are special files called directories. These are the current directory and the parent directory. To see what .* matches, just do this:

echo /home/user/.*

You'll see a huge number of files and directories because .. was matched and you are seeing /home contents. You can imagine the disaster that would happen if you typed: rm -rf /home/user/.* (every file and directory in /home will be removed).

cp (and commands like rm mv ls) do not know anything special about *. This (and other special characters) are pattern matching characters used by the shell to expand into matching filenames. That's why using the echo command in front of a command line with filename patterns is so useful. To see this at work:

echo '*'
echo *

The first returns a * because the single quotes remove the special meaning of * while the second line asks the shell to replace * with a set of matching filenames.

An easy to remember incantation to pickup the . files (without picking the parent directories with .*) is to use .??* which means: matching filenames must start with a dot, followed by at least 2 additional characters. This prevents .. from matching (it's only 2 chars and the mask requires 3 or more). But this mask will miss files like .1 .2 .a .b and so on.

After all this, you can use the -r option for cp and eliminate any filename matching problems:

cp -r /home/user /someplace_else


Bill Hassell, sysadmin
Borislav Perkov
Respected Contributor

Re: Using * doesn't copy all files.

Hi Jonathan,

you can try with tar:

cd fromdir ; tar cf - . | ( cd todir ; tar xf - )

Regards,
Borislav
원유광
Advisor

Re: Using * doesn't copy all files.

Hi..

fistly, You have to login root user

#cp -rp /home/user/. {/destnation dir}

good luck~
Muthukumar_5
Honored Contributor

Re: Using * doesn't copy all files.

If you want to copy only the files in /home/user/ directory then,

find /home/user -type f -exec cp {} \;

It will do.

cp /home/user/[A-Za-z]* will also require -R when you are having directory there in /home/user/

hth.
Easy to suggest when don't know about the problem!
Michael D. Zorn
Regular Advisor

Re: Using * doesn't copy all files.

For the group: Is there any advantage (or dis-) to using something like

for f in $(ls -a /home/user/)
do
cp $f Destination
done

I probably would have forgotten the -a but for this thread, and in trying it out, it looks like you also need -R if there are subdirectories.

If there's a really large number of files, is there a limit to the number of characters that * can expand into?
Wayne Patton_1
Advisor

Re: Using * doesn't copy all files.

Here is what I do to copy all file.

find /home/user -print | cpio -pvmud /target_dir

To get just the ones that start with "."

find /home/user -name ".*" -print | cpio -pvmud /target_dir

This method includes subdirectories and will create said subdirectory structure under the target dir.

wayne

dirk dierickx
Honored Contributor

Re: Using * doesn't copy all files.

if that directory only contains '.' files and all of them need to be copied, you can also just reference to the directory and it will copy everything including hidden files.

so instead of '/home/user/*' you use '/home/user', at least with GNU-cp this works.