177

My goal is copy only all files from ~/local_dir to [email protected] /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

Edgaras Karka
  • 2,447
  • 5
  • 15
  • 14

5 Answers5

228

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

$ scp -r ~/local_dir [email protected]:/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.

parazyd
  • 2,429
  • 1
  • 10
  • 6
63

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

$ scp ~/local_dir/* [email protected]:/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.

Dmitry Grigoryev
  • 7,123
  • 2
  • 23
  • 62
tachomi
  • 7,372
  • 4
  • 25
  • 45
30

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/. [email protected]:/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.

raphinesse
  • 403
  • 4
  • 6
  • 6
    Unfortunately, this solution has been broken by a poorly implemented `scp` "bugfix" (see ). – rivy Jun 28 '20 at 21:14
16

Follow these steps:

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

    scp -r ~/local_dir [email protected]:/var/www/html/target_dir
    
  2. copy only the contents of local_dir and not the directory local_dir itself:

    scp -r ~/local_dir/* [email protected]:/var/www/html/target_dir
    
  3. Do not use: scp -r ~/local_dir/. [email protected]:/var/www/html/target_dir as it throws an error(just tested and received the following error):

    scp: error: unexpected filename: .
    
roaima
  • 107,089
  • 14
  • 139
  • 261
Syed Faraz Umar
  • 261
  • 2
  • 4
  • 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 08 '20 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](https://www.tecmint.com/use-wildcards-to-match-filenames-in-linux/) – Syed Faraz Umar Jan 14 '20 at 06: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 '20 at 08: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 '20 at 09:59
1

Also

rsync -avP ~/local_dir/ [email protected]:/var/www/html/target_dir/

should work.

And you can run it with -n at its end

rsync -avP ~/local_dir/ [email protected]:/var/www/html/target_dir -n

so that it simulates the operation and you can check that the result is what you wish for.

Tms91
  • 113
  • 5
  • 1
    You would need to add a trailing `/` to `~/local_dir` (i.e. `rsync -avP ~/local_dir/ etc.`) to prevent the creation of `/var/www/html/target_dir/local_dir` on the destination side, which is one key requirement of the OP. – AdminBee Jul 16 '21 at 13:27