使用scp命令进行文件传输

换到mac之后,先未尝试找xshell的替代品,而是想把scp命令给配置起来,这样哪怕没找到好用的ftp工具,也能通过终端完成文件的传输。主要目标有2个:

  1. 文件双向传输;
  2. 传输的免密设置。

本篇记录这些内容的要点。

学习参考:https://www.cnblogs.com/peida/archive/2013/03/15/2960802.html

scp命令用法

  1. 命令格式:
    scp [参数] [原路径] [目标路径]

  2. 命令常用参数:
    -B 使用批处理模式(传输过程中不询问传输口令或短语)
    -C 允许压缩。(将-C标志传递给ssh,从而打开压缩功能)
    -r 递归复制整个目录。 目录传输时要用到这个
    -v 详细方式显示输出。scp和ssh(1)会显示出整个过程的调试信息。这些信息用于调试连接,验证和配置问题。
    -i identity_file 从指定文件中读取传输时使用的密钥文件,此参数直接传递给ssh。 这个有用,如果要连接的目标主机只允许使用ssh密钥文件登录,那么scp命令也就必须使用密钥文件才能传输文件,-i参数用来指定目标主机的ssh私钥文件
    -P port 注意是大写的P, port是指定数据传输用到的端口号。这个有用,ssh连接可能用的不是22端口

scp使用举例

先准备mac主机里面需要使用的文件夹及文件:(隐私原因文件夹名称有被修改,下面代码的三角形是因为我使用了zsh作为终端,并且启用了zsh的主题,所以样式不太一样)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
~/liuyunzhuge                                                                       
pwd
/Users/administrator/liuyunzhuge

~/liuyunzhuge
▶ mkdir scp_of_mac

~/liuyunzhuge
▶ mkdir scp_of_centos

~/liuyunzhuge
▶ ls
blog scp_of_centos soft_package
centos_share scp_of_mac virtual_machine

~/liuyunzhuge
cd scp_of_mac

~/liuyunzhuge/scp_of_mac
▶ touch file_of_mac

~/liuyunzhuge/scp_of_mac
▶ vim file_of_mac

~/liuyunzhuge/scp_of_mac
▶ mkdir dir_of_mac

~/liuyunzhuge/scp_of_mac
▶ cp file_of_mac dir_of_mac

scp_of_mac准备放置mac本身的文件及文件夹。scp_of_centos准备放置从centos虚拟机复制过来的文件夹。

进入centos虚拟机,准备虚拟机内的文件夹及文件。

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# cd ~
[root@localhost ~]# mkdir scp_of_mac
[root@localhost ~]# mkdir scp_of_centos
[root@localhost ~]# cd scp_of_centos/
[root@localhost scp_of_centos]# touch file_of_centos
[root@localhost scp_of_centos]# vim file_of_centos
[root@localhost scp_of_centos]# mkdir dir_of_centos
[root@localhost scp_of_centos]# cp file_of_centos dir_of_centos/
[root@localhost scp_of_centos]# ls
dir_of_centos file_of_centos

scp_of_centos准备放置centos本身的文件及文件夹。scp_of_mac准备放置从mac主机复制过来的文件夹。

从虚拟机拷贝文件到mac主机

运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
~/liuyunzhuge                                                                       
▶ scp root@192.168.56.103:/root/scp_of_centos/file_of_centos /Users/administrator/liuyunzhuge/scp_of_centos
root@192.168.56.103's password:
file_of_centos 100% 15 22.9KB/s 00:00

~/liuyunzhuge
▶ cd scp_of_centos

~/liuyunzhuge/scp_of_centos
▶ ls
file_of_centos

~/liuyunzhuge/scp_of_centos
▶ cat file_of_centos
file_of_centos

以上命令把虚拟机的scp_of_centos/file_of_centos这个文件,拷贝到了mac主机的scp_of_centos/目录下。scp默认情况下需要输入密码,所以上面的命令执行会提示输入密码。

也可以在拷贝的时候进行文件重命名:

1
2
3
4
5
6
7
8
~/liuyunzhuge/scp_of_centos                                                         
▶ scp root@192.168.56.103:/root/scp_of_centos/file_of_centos /Users/administrator/liuyunzhuge/scp_of_centos/file_of_centos_copy
root@192.168.56.103's password:
file_of_centos 100% 15 23.7KB/s 00:00

~/liuyunzhuge/scp_of_centos
▶ ls
file_of_centos file_of_centos_copy

如果目标目录中,已存在被拷贝的文件,会直接覆盖,所以要小心。

从虚拟机拷贝文件夹到mac主机

运行:

1
2
3
4
5
6
7
8
~/liuyunzhuge/scp_of_centos                                                         
▶ scp -r root@192.168.56.103:/root/scp_of_centos/dir_of_centos /Users/administrator/liuyunzhuge/scp_of_centos/
root@192.168.56.103's password:
file_of_centos 100% 15 21.9KB/s 00:00

~/liuyunzhuge/scp_of_centos
▶ ls
dir_of_centos file_of_centos file_of_centos_copy

文件夹的拷贝用到-r参数。

也可以在拷贝的时候进行文件重命名:

1
2
3
4
5
6
7
8
~/liuyunzhuge/scp_of_centos                                                         
▶ scp -r root@192.168.56.103:/root/scp_of_centos/dir_of_centos /Users/administrator/liuyunzhuge/scp_of_centos/dir_of_centos_copy
root@192.168.56.103's password:
file_of_centos 100% 15 22.5KB/s 00:00

~/liuyunzhuge/scp_of_centos
▶ ls
dir_of_centos dir_of_centos_copy file_of_centos file_of_centos_copy

如果目标路径中包含不存在的目录,会报错:

1
2
3
4
~/liuyunzhuge/scp_of_centos                                                         
▶ scp -r root@192.168.56.103:/root/scp_of_centos/dir_of_centos /Users/administrator/liuyunzhuge/scp_of_centos/sub1/sub2/sub3/dir_of_centos_copy
root@192.168.56.103's password:
/Users/administrator/liuyunzhuge/scp_of_centos/sub1/sub2/sub3/dir_of_centos_copy: No such file or directory

从mac主机拷贝文件到虚拟机

这个点以及下一个点都有一个变通的做法。就是把上面两个举例的方式,进入虚拟机里面再做。这样的话,从主机往虚拟机上同步文件,就跟虚拟机往主机同步文件,是一模一样的的操作。

也可以继续选在在mac主机里面使用scp命令,只要把上面scp命令使用的源路径与目标路径互换位置即可。
运行:

1
2
3
4
5
6
7
8
9
10
11
~/liuyunzhuge                                                                       
cd scp_of_mac

~/liuyunzhuge/scp_of_mac
▶ ls
dir_of_mac file_of_mac

~/liuyunzhuge/scp_of_mac
▶ scp file_of_mac root@192.168.56.103:/root/scp_of_mac
root@192.168.56.103's password:
file_of_mac 100% 12 4.7KB/s 00:00

以上命令,在mac主机上运行,直接把mac的文件复制到了虚拟机。进入虚拟机可查看:

1
2
3
[root@localhost ~]# cd scp_of_mac
[root@localhost scp_of_mac]# ls
file_of_mac

也可以在拷贝的时候,重命名:

1
2
3
4
~/liuyunzhuge/scp_of_mac                                                           ⍉
▶ scp file_of_mac root@192.168.56.103:/root/scp_of_mac/file_of_mac_copy
root@192.168.56.103's password:
file_of_mac 100% 12 5.3KB/s 00:00

以上命令把file_of_mac拷贝到虚拟机,同时完成了文件重命名。进入虚拟机查看:

1
2
[root@localhost scp_of_mac]# ls
file_of_mac file_of_mac_copy

从mac直接拷贝文件夹到虚拟机

运行:

1
2
3
4
~/liuyunzhuge/scp_of_mac                                                            
▶ scp -r dir_of_mac root@192.168.56.103:/root/scp_of_mac
root@192.168.56.103's password:
file_of_mac 100% 12 4.4KB/s 00:00

以上命令用到-r参数。

亦可在拷贝的时候重命名文件夹:

1
2
3
4
~/liuyunzhuge/scp_of_mac                                                            
▶ scp -r dir_of_mac root@192.168.56.103:/root/scp_of_mac/dir_of_mac_copy
root@192.168.56.103's password:
file_of_mac 100% 12 5.7KB/s 00:00

进入虚拟机查看:

1
2
[root@localhost scp_of_mac]# ls
dir_of_mac dir_of_mac_copy file_of_mac file_of_mac_copy

可能遇到的问题

错误:Permission denied, please try again。
这是ssh的权限问题,修改权限即可,进入到/etc/ssh文件夹下,
用root用户修改文件sshd_config,
将PermitRootLogin no / without-password 改为 PermitRootLogin yes,然后重启sshd服务。
重启ssh:service ssh restart。

scp免密传输

基于ssh的密钥文件,可以实现scp免密传输。原则上,需要把scp命令的源主机的ssh公钥文件添加到目标主机的authorized_keys文件中;但是也可以把目标主机的ssh公钥文件放置到自己的authorized_keys文件中,把自己的ssh的私钥文件发送给源主机,然后源主机在使用scp命令的时候用-i参数指定私钥文件进行传输。

这两个方法本质是一样的,scp在不指定-i参数的时候,肯定用的是自己的私钥文件,当你指定了别的文件以后,就启用别的了。第二种办法有缺点,就是不该随便传递私钥文件,这样不安全,但是也有自己的使用场景,比如源主机上进行scp的用户不具备ssh的权限时。

理解了scp免密的本质,就容易理解如何进行单向免密设置,以及双向免密设置。

本篇仅介绍单向免密设置。

单向免密设置

检查mac主机的用户目录是否有.ssh文件夹,没有则创建。

运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
~/.ssh                                                                         
▶ ls
known_hosts

~/.ssh
▶ ssh-keygen -b 1024 -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/administrator/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/administrator/.ssh/id_rsa.
Your public key has been saved in /Users/administrator/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:LjodC0k+SjyGBQPqi/nDH/s4kYTCBtR5sRpe4CIUbzI administrator@administratordeMBP.lan
The key's randomart image is:
+---[RSA 1024]----+
|++o.... |
|* oo... |
|=E *.o |
|+oO * |
|.* * o S |
|o.* B .. |
|o= o.=.o. |
| .+ o=o. |
| .o=+. |
+----[SHA256]-----+

生成mac主机的ssh密钥文件,其中id_rsa是私钥文件,id_ras.pub是公钥文件。生成过程中提示输入的passphrase不要写,否则scp的时候又得输入密钥文件的密码了。。

进入虚拟机,进入用户目录,查看是否有.ssh目录,没有则创建。

进入.ssh目录,查看是否有authorized_keys文件,没有则创建:

1
2
3
[root@localhost ~]# mkdir .ssh
[root@localhost ~]# cd .ssh
[root@localhost .ssh]# touch authorized_keys

回到mac主机,将.ssh/rd_rsa.pub拷贝到虚拟机的.ssh目录。

1
2
3
4
5
6
7
8
9
10
11
~/.ssh                                                                             ⍉
▶ ll
total 24
-rw------- 1 administrator staff 1.0K 6 16 14:28 id_rsa
-rw-r--r-- 1 administrator staff 242B 6 16 14:28 id_rsa.pub
-rw-r--r-- 1 administrator staff 1.5K 6 15 13:14 known_hosts

~/.ssh
▶ scp id_rsa.pub root@192.168.56.103:/root/.ssh/mac_id_rsa.pub
root@192.168.56.103's password:
id_rsa.pub 100% 242 195.5KB/s 00:00

回到虚拟机,查看.ssh目录

1
2
3
4
[root@localhost .ssh]# ll
总用量 4
-rw-r--r-- 1 root root 0 6月 16 14:32 authorized_keys
-rw-r--r-- 1 root root 242 6月 16 14:37 mac_id_rsa.pub

将mac_id_rsa.pub的内容追加到authorized_keys文件内。

1
cat mac_id_rsa.pub >> authorized_keys

回到mac主机,随便测试一个scp操作,看看是否还需要输入密码。

1
2
3
~/liuyunzhuge/scp_of_centos                                                              
▶ scp root@192.168.56.103:/root/scp_of_centos/file_of_centos /Users/administrator/liuyunzhuge/scp_of_centos
file_of_centos 100% 15 23.4KB/s 00:00

已经不需要密码了。

补充

  1. 使用scp命令的用户,应该跟目标主机进行ssh连接的用户,具有相同的用户名
  2. authorized_keys文件之所以要采用追加的方式,是因为一个服务器可能不止一个源主机想跟它进行免密传输,authorized_keys里面包含了所有源主机的ssh公钥文件。