[译] SSH 与 SCP:使用方法、小窍门与技巧

2,575 阅读6分钟

原文地址: SSH and SCP: Howto, tips & tricks

版权归原作者所有!


这是关于 SSH 和 SCP 的教程。你将学习如何连接到一个远程主机及在主机之间进行复制。本教程还记录了一些重要的命令之间的区别。 困难级别:基础

前言:在本教程中,你将接触到 SSH 和 ssh。不同之处在于:SSH 是通用协议,ssh 是 linux SSH 客户端命令。

SSH

SSH 是某种 Secure SHell 的缩写。这是一个允许计算机之间的安全连接的协议。在本教程中,我们将处理Linux上的 ssh 命令(OpenSSH 版本)。今天大多数 Linux 发行版都自带 OpenSSH 客户端,但是如果你想要确定,看看系统上的 SSH manpage,你可以输入:

$ man ssh

如果你看到这样的文字

NAME
    ssh -- OpenSSH SSH client (remote login program)

那就可以确定你在运行 OpenSSH 版本。更多有关于 SSH 的背景信息,请阅读维基百科-SSH

最简单的情况

在最简单的情况下,你可以连接到一台支持 ssh 的服务器,其语法如下:

[pineehad@localhost ~] $ ssh yourserver

注意:如果你手边没有可以访问的 ssh 服务器,你也可以使用自己的计算机作为服务器来尝试此命令。为此,请将 yourserver替换为localhost

当然,应该用你要连接的服务器的主机名或 IP 地址替换yourserver。在终端代码段中你可以看到,我以 pineehad 的身份登录。如果您没有指定用户名(我将在本教程后面解释如何执行此操作),SSH 将假定您要使用当前登录的用户名登录。因此,在这种情况下,SSH 将尝试用户名 pineehad。

当然,你需要确保服务器支持 ssh 连接。ssh 客户端默认尝试连接到端口22。这意味着,如果要使用默认设置连接到远程主机,则应确保端口22(如果适用)转发到你尝试连接的服务器。你将在本教程中进一步了解有关SSH端口的更多信息。

回到我们运行的命令。如果服务器支持 SSH 连接并且您可以通过端口22访问它,则应提示你输入密码(如果这是你第一次尝试连接到服务器,ssh 将首先询问您是否要继续连接的问题,通常就回答 yes)。如果你在此处键入密码,不会出现星号。别慌,这是 ssh 的正常行为,这样能让 ssh 连接更加安全,因为旁观者都无法看到密码的长度。输入密码后,如果用户名和密码正确,那么你现在就应该是在服务器上运行 shell了。如果没有,请确保连接到一台能够使用你的用户名和指定密码登录的服务器。你可以尝试连接到自己的计算机或继续阅读以了解如何指定其他用户名。

尝试完 ssh shell 后,可以按 Ctrl + D 退出。

指定端口

将 ssh 服务移动到其他端口的原因有很多。其中之一是避免暴力登录尝试。某些黑客试图通过尝试使用大量常见用户名和密码来访问ssh服务器(例如用户名“zhangsan”和密码“1234”)。虽然这些黑客不太可能访问系统,但是你通常要避免的暴力攻击的另一个方面:系统负载和连接负载。暴力攻击通常每秒进行几十次甚至几千次尝试,这会拖慢服务器的速度并占用一些可用带宽。通过将端口更改为非默认端口,黑客的脚本将被拒绝,大部分带宽将被节约。

由于 ssh 命令不能猜测端口,如果不使用默认的22,我们就必须要指定。你可以这样做:

[pineehad @ localhost~] $ ssh -p yourport yourusername@yourserver

当然,您必须将“yourport”替换为端口号。则是 ssh 和 scp 之间的重要区别,后文中我会进一步解释。

在远程服务器上运行命令

有时,特别是在脚本中,你需要连接到远程服务器,运行单个命令然后再次退出。对于这个需求 ssh 命令有一个很好的特性:你只需在选项(用户名和密码)后指定命令即可。

[pineehad@localhost ~]$ ssh yourusername@yourserver updatedb

这将使服务器更新其搜索数据库。当然,这是一个没有参数的非常简单的命令。如果你想告诉别人您在网上看到的最新消息怎么办?你可能会认为以下内容会给他/她这条消息:

[pineehad @ localhost~] $ ssh yourusername@yourserver wall "Hey, I just found out something great! Have a look at www.examplenewslink.com!"

但是,如果运行此命令,bash 将给出错误:

bash: !": event not found

发生了什么? Bash(你的 shell 背后的程序)试图解释你的 ssh 命令。因为命令中有感叹号,bash 会将其解释为启动 bash 函数的特殊字符,所以失败了。但是这并非我们的用意,我们只想要 bash 给 ssh 发送命令!有一种非常简单的方法可以告诉 bash 不要担心命令的内容,而只是将其传递给ssh:用单引号将其包装起来。

[pineehad@localhost ~]$ ssh yourusername@yourserver 'wall "Hey, I just found out something great! Have a look at www.examplenewslink.com!"'

单引号阻止 bash 尝试解释命令,因此 ssh 会不加修改地接收它,并且可以将其发送到服务器。不要忘记单引号应该围绕整个命令,而不是其他任何地方。

SCP

scp 命令可以让你通过 ssh 连接复制文件。如果要在计算机之间传输文件(例如备份某些内容),这个命令是非常有用的。scp 命令使用 ssh 命令,它们非常相似。但是,两者间存在一些重要的差异。

scp 命令有三种使用方式:从(远程)服务器复制到计算机,从计算机复制到(远程)服务器,以及从(远程)服务器复制到另一个(远程)服务器。在第三种情况下,数据直接在服务器之间传输;你自己的计算机只会告诉服务器该做什么。这些选项对于许多需要传输文件的东西非常有用,所以让我们看一下这个命令的语法:

[pineehad@localhost ~]$ scp examplefile yourusername@yourserver:/home/yourusername/

看起来很熟悉吧?但是存在差异。上面的命令会尝试使用用户名“yourusername”获取 ssh 连接,将文件“examplefile”传输到服务器“yourserver”的目录“/home/yourusername/”。信息量很大,scp 的确全部都需要。或者说,几乎全部需要。“yourserver”前面的“yourusername @”是可以省略的,但前提是你要在自己的计算机上使用当前用户名登录服务器。让我们仔细看看命令的结尾。有一个冒号,后面有一个目录。就像 Linux 的普通 cp 命令一样,scp 需要知道源文件和目标目录(或文件)。对于远程主机,文件/目录要以这种方式传给 scp 命令。

你还可以将文件(或多个文件)从(远程)服务器复制到您自己的计算机。我们来看一个例子:

[pineehad@localhost ~]$ scp yourusername@yourserver:/home/yourusername/examplefile .

注意:末尾的点表示当前的本地目录。这是一个方便的技巧,可用于 Linux 中的任何地方。除了单个点,您还可以键入双点(..),它是当前目录的父目录。

这会将文件“/home/yourusername/examplefile”复制到你自己的计算机的当前目录中,前提是用户名和密码正确且文件实际存在。

你可能已经能够猜到以下命令将文件从(远程)服务器复制到另一个(远程)服务器:

[pineehad@localhost ~]$ scp yourusername@yourserver:/home/yourusername/examplefile yourusername2@yourserver2:/home/yourusername2/

请注意,要使上述命令有效,服务器必须能够相互访问,因为数据将直接在它们之间传输。如果服务器因为某些原因无法相互连接(例如,如果端口22未在其中一侧打开),你将无法复制任何内容。在这种情况下,首先将文件复制到你自己的计算机,然后再复制到另一台主机上。或者使服务器能够相互联系(例如通过打开端口)。

这些是 scp 的主要用途了。我们现在将更深入地了解 ssh 和 scp 之间的差异。

*:实际上你也可以像普通的cp命令一样使用它,但没有任何ssh连接,但这么做没有什么意义,因为还要多打一个“s”。

scp 指定端口

scp 命令在端口方面有一点不同。你可能觉得指定一个端口应该这样做:

[pineehad@localhost ~]$ scp -p yourport yourusername@yourserver:/home/yourusername/examplefile .

但是,这样不好使。你将看到如下错误消息:

cp: cannot stat `yourport': No such file or directory

这是由 scp 的架构不同引起的。scp 设计上类似于 cp,而 cp 也具有 -p 选项。但是,在 cp 术语中它表示“保留(preserve)”,它会导致 cp 命令保留所有权、权限和创建日期等内容。 scp命令也可以保留这样的内容,-p 选项启用此功能。端口指定应使用 -P 选项完成。

[pineehad@localhost ~]$ scp -P yourport yourusername@yourserver:/home/yourusername/examplefile .

另外要注意,-P 选项必须位于(远程)服务器的前面。如果将 -P yourport 放在主机语法后面,ssh 命令仍然可以工作,但 scp 不会。为什么?因为 scp 还支持在两个服务器之间进行复制,因此需要知道 -P 选项作用于哪个服务器。

scp 和 ssh 之间的另一个区别

与 ssh 不同,scp 不能用于在(远程)服务器上运行命令,因为它已经使用 ssh 的这一功能来启动主机上的 scp 服务器。 scp 命令确实是有一个接受程序的选项(-S 选项),但是这个程序将被用来代替 ssh 来建立加密连接,它不会在远程主机上执行。

使用 ssh 和 scp 的小窍门和技巧

scp 有一个方便的特性是它支持星号。你可以通过以下方式复制远程目录中的所有文件:

[pineehad@localhost ~]$ scp yourusername@yourserver:/home/yourusername/* .

您还可以通过指定-r(递归)选项来复制整个目录:

[pineehad@localhost ~] $ scp -r yourusername@yourserver:/home/yourusername/ .

这两种方法在复制到(远程)服务器或在(远程)服务器和另一个(远程)服务器之间复制时也可以使用。

如果你不知道要使用 scp 复制的文件的确切位置,则 ssh 命令可以派上用场。首先,ssh 到(远程)服务器:

[pineehad@localhost ~]$ ssh yourusername@yourserver

然后使用 cd 浏览到正确的目录。这是 Linux 终端必备的知识,不再细说。当你在正确的目录中时,可以使用此命令获取完整路径:

[pineehad@localhost ~] $ pwd

注意:pwd是Print Working Directory的缩写,这是记住命令的有用方法。

然后,你可以复制此输出,按 Ctrl + D 离开 ssh shell,然后在 scp 命令中粘贴完整的目录路径,不用再靠记忆和打字了!

你还可以限制 scp 在复制时使用的带宽。如果你不想在慢网的情况下复制大量数据浪费费时间,这非常有用。以这种方式限制带宽:

scp -l bandwidthlimit yourusername@yourserver:/home/yourusername/* .

带宽以 千比特/秒 为单位。这是什么意思呢?8比特是1个字节。如果要复制速度不超过 10 Kbyte/sec,请将限制设置为80。如果要复制速度不超过80 Kbyte/sec,请将限制设置为 640。即应该将限制设置为你希望的最大的千比特/秒的8倍。我建议你将 -l 选项给所有在与他人共享的的连接上执行的 scp 都设置上。如果您使用集线器,大量复制会阻塞整个10 Mbit网络。