94

My goal is copy only all files from ~/local_dir to user@host.com /var/www/html/target_dir using scp and do not create local_dir category in local_dir.

/var/www/html/target_dir/files..

but not

/var/www/html/target_dir/local_dir/files.. when use -r parameter

  • 1
    Does scp * user@host.com:/var/www/html/target_dir not do what you want? If so, please edit with more detail of what you're trying to do & have tried so far. – Michael Homer Sep 30 '15 at 8:05
  • Appending /. is no longer work. More here – Tsulatsi Tamim Mar 20 '19 at 9:13
133

scp has the -r argument. So, try using:

$ scp -r ~/local_dir user@host.com:/var/www/html/target_dir

The -r argument works just like the -r arg in cp, it will transfer your entire folder and all the files and subdirectories inside.

| improve this answer | |
  • 12
    Your command created local_dir directory in /var/www/html/target_dir my goal is copy only files. – Edgaras Karka Sep 30 '15 at 8:25
  • 1
    Sorry, I got it wrong. Then just repeat the command, but like this: $ scp -r ~/local_dir user@host.com:/var/www/html/ Then rename new directory if needed. – parazyd Sep 30 '15 at 8:31
  • 8
    Or $ scp -r ~/local_dir/* user@host.com:/var/www/html/target_dir Whatever floats your boat. – parazyd Sep 30 '15 at 8:34
  • 18
    Change the wildcard * to a dot . and you'll copy the directory contents (including any dot files) without copying the directory itself. scp -pr ~/local_dir/. user@example.com:/path/to/target_dir – roaima Jul 21 '17 at 22:25
  • Another alternate format is pushd local_dir; scp -r . user@host.com:/var/www/html/target_dir; popd bash provides many ways to say much the same thing. – Jesse Chisholm Dec 9 '19 at 21:18
29

If your goal is to transfer all files from local_dir the * wildcard does the trick:

$ scp ~/local_dir/* user@host.com:/var/www/html/target_dir

The -r option means "recursively", so you must write it when you're trying to transfer an entire directory or several directories.

From man scp:

-r 
Recursively copy entire directories. Note that scp follows symbolic links encountered in the tree traversal.

So if you have sub-directories inside local_dir, the last example will only transfer files, but if you set the -r option, it will transfer files and directories.

| improve this answer | |
  • 2
    1+ Because you need to read the comments in the accepted answer to get to the correct answer, while this one just explains it directly. – André Christoffer Andersen Jul 5 '17 at 10:01
21

Appending /. to your source directory will transfer its contents instead of the directory itself. In contrast to the wildcard solution, this will include any hidden files too.

$ scp -r ~/local_dir/. user@host.com:/var/www/html/target_dir

Credit for this solution goes to roaima, but I thought it should be posted as an actual answer, not only a comment.

| improve this answer | |
6

Follow these steps:

  1. Copy directory local_dir with all its sub-directories:

    scp -r ~/local_dir user@host.com /var/www/html/target_dir
    
  2. copy only the contents of local_dir and not the directory local_dir itself:

    scp -r ~/local_dir/* user@host.com /var/www/html/target_dir
    
  3. Do not use: scp -r ~/local_dir/. user@host.com /var/www/html/target_dir as it throws an error(just tested and received the following error):

    scp: error: unexpected filename: .
    
| improve this answer | |
  • 1
    I also get the error of unexpected filename . However, using the wildcard does not work either cause the directory has so many files that is exceeds the character limit for commands when the wildcard gets expanded. macOS – Richard Kiefer Jan 8 at 10:17
  • @RichardKiefer : You can use wildcards like ? with * to further isolate the search results and then pass it to scp. Try this link, it may help: Wildcards – Syed Faraz Umar Jan 14 at 6:15
  • Thanks Syed, but my point was that I actually want to target all elements in the folder, and not filter any. And if my directory has too many, than the wildcard will just not work. – Richard Kiefer Jan 14 at 8:33
  • @RichardKiefer: My apologies Richard, to get all the files copied we can use a small bash script. Use: ls -l | awk '{print $9}' and redirect all the output (which would be all the file names) to a txt file. Read the txt file, one line at a time and use that input with scp to copy the files: input=/home/user/filename.txt while IFS= read -r line – Syed Faraz Umar Jan 14 at 9:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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