解决ssh连接linux服务器速度慢

核心:

服务器端sshd配置文件 /etc/ssh/sshd_config 看是否有如下的两条配置条目

GSSAPIAuthentication no
UseDNS no

如果前面带#,请把#删掉,或者新添加入这样两行。
然后重启sshd服务,或者重启服务器也可以。

注意是文件 /etc/ssh/sshd_config 而不是/etc/ssh/ssh_config

 

ssh 登录远程服务器,速度非常慢,通过网上查询,发现有一个参数 -v 可以输出显示连接的具体消息。于是连接加上这个参数连接

[feng@fsc ~]$ ssh -v foo.path8.net
OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 Mar 2010
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to v.path8.net [64.120.xxx.xxx] port 22.
debug1: Connection established.
debug1: identity file /home/feng/.ssh/identity type -1
debug1: identity file /home/feng/.ssh/id_rsa type 1
debug1: identity file /home/feng/.ssh/id_dsa type -1
debug1: Remote protocol version 2.0, remote software version OpenSSH_5.3
debug1: match: OpenSSH_5.3 pat OpenSSH*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_5.3
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Host 'v.path8.net' is known and matches the RSA host key.
debug1: Found key in /home/feng/.ssh/known_hosts:4
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug1: Next authentication method: gssapi-keyex
debug1: No valid Key exchange context
debug1: Next authentication method: gssapi-with-mic
/*--------- 这里停留的十多秒钟时间 ----------*/
reverse mapping checking getaddrinfo for srv3.mktmaster.net [64.120.xxx.xxx] failed - POSSIBLE BREAK-IN ATTEMPT!
debug1: Unspecified GSS failure.  Minor code may provide more information
Credentials cache file '/tmp/krb5cc_501' not found

debug1: Unspecified GSS failure.  Minor code may provide more information
Credentials cache file '/tmp/krb5cc_501' not found

debug1: Unspecified GSS failure.  Minor code may provide more information


debug1: Next authentication method: publickey
debug1: Offering public key: /home/feng/.ssh/id_rsa
debug1: Server accepts key: pkalg ssh-rsa blen 277
debug1: Authentication succeeded (publickey).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env XMODIFIERS = @im=ibus
debug1: Sending env LANG = zh_CN.utf8
Last login: Mon Oct 24 10:26:30 2011 from 124.79.xxx.xxx
[feng@v ~]$

大概就是GSSAPIAuthentication这个参数的问题了,之前就是因为连接速度慢,网上查,说是/etc/ssh/sshd_config 里加入参数 UseDNS no,再加个GSSAPIAuthentication yes, 结果速度还是慢。
于是去把这行改为GSSAPIAuthentication no,重启服务器端的ssdh服务,再次连接,速度快多了。

参考

putty详细使用说明 (windows下)

PuTTY 是一个跨平台的远程登录工具,包含了一组程序,包括:

  • PuTTY (Telnet 和 SSH 客户端)
  • PSCP (SCP 客户端, 命令行下通过 SSH 拷贝文件,类似于 Unix/Linux 下的 scp 命令)
  • PSFTP (SFTP 的命令行客户端,类似于 FTP 的文件传输,只不过使用的是 SSH 的 22 端口,而非 FTP 的 21 端口,类似于 Unix/Linux 下的 sftp 命令)
  • PuTTYtel (仅仅是一个 Telnet 客户端)
  • Plink (命令行工具,执行远程服务器上的命令)
  • Pageant (PuTTY、PSCP、Plink 的 SSH 认证代理,用这个可以不用每次都输入口令了)
  • PuTTYgen (用来生成 RSA 和 DSA 密钥的工具).

虽然包含了这么多,但平时经常见到只是用 PuTTY 登录服务器,完全没有发挥出 PuTTY 的强大功能。
PuTTY 作为一个组件也存在于很多的软件中,比如 FileZilla、WinSCP
在后面的文字中,如非特别说明,默认的登录的协议是 SSH。毕竟用 PuTTY 主要就是登录 SSH 主机,用 Telnet、RLogin 没法体现出 PuTTY 的强大功能。
安装
PuTTY 是一个跨平台的远程登录工具,包含了一组程序,包括:

  • PuTTY (Telnet 和 SSH 客户端)
  • PSCP (SCP 客户端, 命令行下通过 SSH 拷贝文件,类似于 Unix/Linux 下的 scp 命令)
  • PSFTP (SFTP 的命令行客户端,类似于 FTP 的文件传输,只不过使用的是 SSH 的 22 端口,而非 FTP 的 21 端口,类似于 Unix/Linux 下的 sftp 命令)
  • PuTTYtel (仅仅是一个 Telnet 客户端)
  • Plink (命令行工具,执行远程服务器上的命令)
  • Pageant (PuTTY、PSCP、Plink 的 SSH 认证代理,用这个可以不用每次都输入口令了)
  • PuTTYgen (用来生成 RSA 和 DSA 密钥的工具).

虽然包含了这么多,但平时经常见到只是用 PuTTY 登录服务器,完全没有发挥出 PuTTY 的强大功能。
PuTTY 作为一个组件也存在于很多的软件中,比如 FileZilla、WinSCP
在后面的文字中,如非特别说明,默认的登录的协议是 SSH。毕竟用 PuTTY 主要就是登录 SSH 主机,用 Telnet、RLogin 没法体现出 PuTTY 的强大功能。

安装

PuTTY 是一个准绿色软件,说它绿色是因为直接就能使用,完全没有任何的安装程序。准绿色是指 PuTTY 的所有配置都保存到了注册表,如果不记得备份注册表中的相关内容,下次重装机器所有配置就没了,而且配置也不方便用闪存盘随身携带。但是 PuTTY 的配置删除还是蛮方便的,运行时指定个参数 -cleanup 就可以清除 PuTTY 的所有配置信息。

第一印象,开始登录一台远程主机

运行 PuTTY 就可以看到下面这个界面

在这里输入服务器的 IP 或主机名,选择好登录协议,还有协议的端口,如果希望把这次的输入保存起来,以后就不需要再重新输入了,就在第4步输入好会话保存的名称,比如:mail-server,或者干脆就是主机的地址,点击保存就可以了

现在问题是:

我的软件是汉化过的(可以从网上找非常小的,只有540多K),但是命令提示信息却是乱码,网上一般的解决办法是针对英文版本如果显示中文字符的。现在招到了一半办法,记录如下,做个资料备份:
echo $LANG $LANGUAGE

查看linux系统的字符集原来系统的字符集是 UTF-8 呀。重新返回上面选择字符集的那一步, 选择配置窗口左边的 Translation,在右边的 Received data assumed to be in which character set 下拉列表中选择“UTF-8”

这下99%的情形下,汉字是不会有乱码了。最后,总之一下 PuTTY 中乱码的解决办法:
先看看系统的字符集,如果是 UTF-8 的,那就简单了,选择好中文字体,然后编码选择 UTF-8 就行了。
如果编码是 GB2312、GBK、GB18030,当然也包括 BIG5这些,在 PuTTY 的编码选择中看不到这些编码,那就选择最后一个“Use font encoding”,绝大部分情况下这样就没啥问题了,反正我是没碰到有什么例外的情况。
现 在的 Linux 如果默认语言选择为中文,默认的编码就是 UTF-8 了。以前安装 Redhat AS 3 时,语言选择为中文,默认的编码是 zh_CN.gb2312, zh_CN.gb18030,好像从 AS 3 update 6 开始,包括现在的 AS4、AS5,中文的默认编码都成了 zh_CN.utf8。至于 Debian、Ubuntu 等等这些上面,好像一直都是 UTF-8。
至于是使用 UTF-8呢,还是用 GB2312、GBK 或者 GB18030呢?我个人还是倾向于 UTF-8。毕竟我们使用的大多数软件都是国外的,处理中文编码多多少少有些问题,PuTTY 自然也不例外。
下面的这个图上,我把终端编码修改为 zh_CN.utf8,然后也按照前面的所说的方法把 PuTTY 的字符集修改为 UTF-8。然后在终端中输入汉字“柴锋”,按左方向键,可以看到汉字显示很正常。

我重新把终端的编码修改为 zh_CN.gb2312,同样的,把 PuTTY 的字符集修改为最后一个“Use font encoding”。还是在终端上输入汉字“柴锋”,按下左方向键以后,会看到汉字乱码了。

至 于用哪个编码,主要还是看领导的决定了,我们的领导就喜欢 GBK,连 GB18030 都不行。以前在用 Debian 的时候,好像默认都不支持 GBK 编码。这几年公司的开发在汉字编码问题上出过几次麻烦,还不就是在 ISO8859-1, GB2312/GBK/GB18030和UTF-8上折腾来折腾去。
给大家看一张 emacs 的截图,看看上面的这么多语言的文字共同显示,这个会是用 GB2312/GBK/GB18030 的编码么?

用 UTF-8 也不是为了要在一个屏幕上显示好几种不认识的文字,也不一定非要是跟国际接轨弄个外包给老外开发程序做个其他语言的界面让老外用,起码不要在那么多编码里折腾了,顶多两个 ISO8859-1 和 UTF-8。发发牢骚,下面继续……

在 PuTTY 里面怎样选中,复制和粘贴?

在 PuTTY 的窗口里面复制、粘贴可不能用 Windows 里的这些 Ctrl+C, Ctrl+Ins, Ctrl+V 这些快捷键,Ctrl+C 在控制台上可是终止当前的命令执行。
PuTTY 的选择、复制、粘贴这些操作都是通过鼠标来完成的。
在 Window-〉Selection 这里可以设置复制和粘贴的方式。

默 认的 Action of mouse buttons (鼠标按键的功能)的选项是 Compromise,这种方式下选中有两种方式,一是直接用鼠标左键拖拉选中就可以了,二是用鼠标中键单击选中区域的开头,用滚动条拖拉到期望选中区域 的末尾,再用鼠标中键单击,就可以选中了。
选中以后,单击鼠标左键就把选中部分复制到剪贴板了。粘贴也很简单,单击鼠标右键。
Action of mouse buttons 的第一个选项是 Windows (Windows 方式的),鼠标中键的操作跟前面提到的一样。右键不是粘贴了,而是打开了右键菜单。

其实这个右键菜单在标题栏上点击,也都可以看得到。

第三个选项是 xterm (xterm 方式),这个跟默认的 Compromise 方式相反的,中键和右键的操作调换了一下,就不多说了。
下 面那个 Shift overrides application’s use of mouse 是和 Shift 键有关的。有些 Rogue Like 的程序,比如 mc、links、Lynx、VIM 等等,都支持鼠标操作,想在用鼠标在上面选择或粘贴就不行了。这个选项默认是选中的,在支持鼠标操作的 Rogue Like 界面下,按住 Shift 键,就可以像前面的那样用鼠标来选择、复制、粘贴了。
看下面的这个图片,用 Links 打开了 Google 的首页,用鼠标去选中 顶部中间的 Google,我们会发现,弹出了保存的对话框。

按住 Shift 键重新操作一次,哈哈,这次选中了。

在 Control use of mouse 里面还有个 Default selection mode (默认的选择模式),默认是 Normal,就像文字处理工具里这样的选择

另外一个是 Rectangular block(块选择方式),至于用哪种方式就看自己的选择了。

实时保存会话

这次更改配置参数了,关闭窗口后,下次使用还是要重新选择的,麻烦。
还是回到上面修改配置的哪个地方,选择左边的 Session,在右边选择要覆盖的会话名称,或者重新输入一个新的名称,点击 Save 按钮保存。

关于注销登录的一些事情

成功登录主机后,也能正常看到中文了。这样,我们就可以完成大部分的工作。最后要关闭窗口了,该怎么办呢?我见过很多人,包括我们公司负责专职维护的同事,都是直接点击窗口上的关闭按钮,完全没有理会弹出警告窗口,直接点击了 Yes。

这样做是不对的,首先这不是正确的注销方式,应该输入命令 exit 来正常注销; 其次直接关闭窗口后,你的登录其实还在服务器上,如果一连多次的这样强制关闭窗口,用命令 w 或者 who 命令查看时,可以看到很多的用户还在系统上登录,占用了系统的资源。最重要的是,你的这次登录可能只是为了启动一下 WebLogic 或者其他什么应用服务器,直接关闭窗口后,可能会导致你的业务在随后的几分钟内也被终止,这应该不是你所希望看到的吧。
如果上述的理由是每次要输入 exit 然后回车,比较麻烦。你可以用快捷键 Ctrl+d 来注销登录,一般情况下,快捷键一按窗口都直接关闭了,还省了两次鼠标点击。
在前面说道保存会话时,大家或许也注意到,下面有个 Close window on exit 有三个选项:

  • Always (不管怎样,窗口总是要关闭的)
  • Never (无论是否有程序还在运行,都不要关闭窗口)
  • Only on clear exit (这个是默认选中的,只有在本次登录中运行的程序都正常终止或者在后台运行,窗口才关闭)

有的程序在执行时,虽然在命令最后面加上 “&”就能放到后台运行。但是正常注销登录后,窗口没有被自动关闭,还能看到程序的输出,这时强制关闭窗口还是可以的。为了避免这种情形,可以使用 nohup 命令。
用法嘛就是: nohup 命令 命令参数,这样就可以了。

窗口保存的输出有点少,前面的都看不到了

执行了一个命令,输出了好多东西,但是默认的配置下,PuTTY只保存了最后200行的内容,满足不了我们的需求。
还是在标题栏上点右键选择 Change settings…,在配置窗口的左边选择 Window,修改右边的 Lines of scrollback,改大点,比如 20000、80000的

在上面的 Set the size of the window 里设置的是窗口显示的行数和列数,默认是 24 行、80 列,根据自己的需要来修改吧。
When window is resized 这个选项配置的是,当窗口大小发生改变时该采取什么动作。

  • Change the number of rows and columns(这个是默认的,改变窗口大小时,自动修改行数和列数)
  • Change the size of the font(这个是根据窗口的大小来修改字体的大小,窗口最大化的时候,字都是很大的)
  • Change font size only when maximised(只有在窗口最大化的时候才改变字体大小)
  • Forbid resizing completely(完全禁止改变窗口大小,一了百了)

在现代的 Unix/Linux 主机上,默认选项已经不存在任何问题了。如果是 Solaris 8 这样的老式 Unix 上最好用第2或第4个选项。
第3个选项嘛,要求你的屏幕不是宽屏的,选中这个选项以后,大家可以先把窗口往窄的缩一下,然后最大化窗口,哈哈,满足一下不是宽屏的虚荣心。
顺便说一下,在 PuTTY 中的前后翻页,与 Linux 终端一样,用 Shift+PageUp/PageDown 来上下翻页,而 Ctrl+PageUp/PageDown 则是一行一行的。

新建一个会话时,还有些东西再啰嗦一下

前面把如何用 PuTTY 登录一台主机到注销的过程聊了一遍,但是在新建会话时还是有些东西需要再啰嗦一下的。

保持连接,不要自动断开

在 Connection 里面有个 Seconds between keepaliaves,这里就是每间隔指定的秒数,就给服务器发送一个空的数据包,来保持连接。以免登录的主机那边在长时间没接到数据后,会自动断开 SSH 的连接。
默认输入 0 是禁用保持连接,在这里我习惯的设置了 10。
下面的那两个复选框都保持默认选中吧。

自动登录用户

在 Connection-〉Data 里面有个 Auto-login username,可以指定默认的登录用户。如果每次登录主机都是用同一个用户,不妨在这里设置一下。SSH、Telnet、Rlogin 这三种协议都支持,但不是所有的 Telnet 服务器支持自动登录用户

自动设置环境变量

还是前面的那个界面,下面有个 Environment variables,在 Variable 输入环境变量的名称,Value里设置上环境变量的值,登录主机后就会自动设置上,但是这个不一定能用,有些主机为了安全,可能会禁用这个特性,一旦登录 就会收到这样一个错误提示:

Server refused to set environment variables

设置代理服务器

这个经常用到,设置方法大同小异,注意选择好 Proxy type(代理服务器的类型)就可以了。
代理服务器的地址填写到 Proxy hostname 这里,Port 就是代理服务的端口(HTTP代理常用端口有 3128、8080,Socks5代理常用端口有 1080)
Exclude Hosts/IPs 这里是填写排除的主机地址和IP,有些地址不需要代理,就在这里填写。
有些代理需要认证,用户名填写到 Username,密码则填写到下面的 Password。

自动执行一个命令

在 Connection-〉SSH 里有个 Remote command,在这里面填写上远程服务器上的某个命令,比如:df,登录后就会自动执行。
我们在 Unix 上用 ssh 登录主机时用的命令 ssh,在 ssh 的最后面加上远程主机上的命令,就跟这个一样。
但是……,先别着急,一旦设置上这个选项,你会发现在登录成功后,窗口一下就关闭了,嘿,怎么啦?什么也没看见。
因为命令执行完毕的同时,本次 SSH 登录连接也随之关闭。

你可以把远程自动执行的命令修改成 sleep 10,然后重新登录,再看看效果。
登录成功后,没有出现命令提示符,10秒钟后,窗口自动关闭。这也验证了刚才我说的,命令执行完毕后,SSH 连接自动断开。
冰雪聪明的你一定会想到,如果每次登录主机,都是要重新启动一下 tomcat,那这里就可以填写上这样的命令:

export CATALINA_HOME=”~/apache-tomcat-5.5.17″;export JAVA_HOME=”~/jdk1.5.0_07″;export PATH=$JAVA_HOME/bin;$PATH ; cd $CATALINA_HOME/bin;./shutdown.sh;./startup.sh;tail -f $CATALINA_HOME/logs/catalina.out

(上面的命令是一行的哦)
先自动设置一下环境变量(前面有提到,服务器可能会禁用自动设置环境变量,为了保险起见,在这里设置了一下),然 后进入 tomcat 的 bin 目录,用 shutdown.sh 停止 tomcat,然后再 startup.sh 启动 tomcat,最后 tail 命令持续观察 tomcat 的日志输出,不想看了,就直接 Ctrl+C 就可以终止 SSH 的会话了。
哈哈,是不是很方便?
不 过前面提到的命令 sleep 10,只是建立了 SSH 连接,然后 10 秒钟后自动断开。是不是觉得很无聊没什么用途啊?其实这个命令配合后面提到的 Tunnels(隧道),可以自动保持隧道一定时间的开放,如果指定时间内(在这里就是 10 秒钟)隧道没有被使用,就自动关闭 SSH 连接和隧道。
如 果选中了 Don’t start a shell or command at all 就禁用了自动执行命令这一个特性,这个主要是配合 Tunnels (隧道)来使用的。因为有时候,我们只需要利用隧道建立一个 VPN,而并不需要登录上去执行命令。用这个方法建立好隧道以后,就一直开放了,除非自己手工关闭。

嗯,还有个问题哦,如果一次要执行的命令很多,该怎么办呢?嗯,给 PuTTY 用 -m 选项指定一个包含远程主机上执行的命令的文本文件。不过以后还会说到 Plink,就是专门做这个用的,慢慢来慢慢来。

数据自动压缩传输,变相的提高传输速率

还是前面的那个界面,Protocol options 里面有个 Enable compression,这个选项的意思就是传输时压缩数据,在连接速度不变的情况下,变相的提高了传输速率。一般的 SSH 服务器都会允许这个选项的,所以还是选中好了。

无需口令登录

在 Connection-〉SSH-〉Auth 这里面有两个需要了解的,以后在讲到 PuTTYGEN 和 Pagent 时会详细介绍的。
一个是 Allow agent forwarding,作用是允许私钥代理的转发。
另外一个是最下面的 Private key file for authentication,选择私钥认证文件。
这 两个可以让你用 SSH 登录不用输入主机口令,但是私钥的口令还是需要输入的,如果使用了私钥代理 Pagent ,私钥口令也可以省略。再配合前面提到的自动指定用户名登录,可以实现自动登录主机。登录到主机上以后,用 SSH 登录另外一个同样配置了相同的私钥认证的主机,也可以不用再次输入口令。
这些可以大大减轻了我们的重复工作,不用单调枯燥的输入用户名和口令,但是这样使用有个后遗症就是如果主机密码没有在另外一个地方记录下来的话,这个密码很快会忘记的,好处嘛,密码可以设置的很长很变态 XD。

X11 转发能够让你在 Windows 上使用 Linux 的程序

这里很简单,选中 Enable X11 forwarding 后登录主机,记得在我们本地运行 X 服务端程序(比如:免费好用的 Xming)。

然后在控制台直接输入 X 环境下运行的程序,比如:xlogo,我们就可以看到 Linux 上的GUI界面的程序在Windows桌面上打开了。

运行个复杂的,比如 gnome-session,这个是 GNOME 的启动命令,如果想打开 KDE 就是 startkde


这样跟在本地使用 X Window 几乎是一样的了,而且还是运行在 Windows 的桌面上呢,骗骗小 mm 还是不错的。或许你会问这样用跟 vnc 那还不一样了?答案是,不一样。如果网络环境不好,还是用vnc吧,否则迟钝的图形响应速度会让你抓狂的。

打开了 GNOME 桌面,怎么关闭呢?点菜单的注销吧。如果你点了关机,这可关不了你的Windows,关的是远程主机。

用 SSH Tunnels(SSH 隧道),突破防火墙

哇哦,突破防火墙!是不是忽然有了做黑客的感觉呢?呀!子弹,我躲——,身子往后仰,继续闪……,噢,肚皮被子弹蹭了一下。
简单的说一下,SSH 协议能够通过已经建立好的 SSH 加密链路来转发任意的网络连接,从而避免了网络中的明文传输,也就无法用一些 Sniffer 工具嗅探到我们的隐秘信息了。
先 说一下大致的使用过程,登录到主机上以后,就可以建立好一个 SSH 隧道,这时在你的机器本地会开放一个端口,通过本地的这个端口访问,就相当于在主机上去直接访问。很像代理服务器吧,如果隧道另一端的端口是动态 的,SSH 隧道就是一个代理了,SSH 隧道的意思大致就是这个。通过 SSH 隧道,我们可以保证从我们这一段到主机那一端是安全的,不会被监听到。
说了这么多,实际演练演练就知道了。在 PuTTY 的 Connection-〉SSH-〉Tunnels 这里就是配置 SSH 隧道的。
Add new forwarded port 这里就是添加隧道转发端口的,其中 Source port 是隧道的源端口,也就是隧道的入口,连接隧道时要连接这个端口。Destination 这里是目的地,隧道的出口,输入的格式是: server:port。
还 要说明的一点是 SSH 隧道是有方向的,这个方向是由下面的单选按钮 Local/Remote/Dynamic 来决定的。如果下面的单选按钮选中的是 Local,那么 Destination 这里填写的目标是相对于远程主机而言,而非你的机器。这样的隧道可以称之为正向隧道,隧道的入口是在你的本地,出口在远程主机那一端。如果单选按钮选中的 是 Remote,那么目标地址就是相对与你的机器而言,而非远程主机。这样的隧道称之为反向隧道,隧道的入口是远程主机那一端,隧道的出口则是你的本地机 器。这与 Local 选项是相反的。而最后一个 Dynamic 则不用指明 Destination 目标地址,也就是说目标地址是动态的了,连入隧道时可以随意指定目标地址,而不像 Local/Remote 指明的固定目标地址,所以这样的隧道就成了变相的加密 socks5 代理服务器了。
看明白了么?是不是会有些糊涂?后面我会举个例子来详细说说的。

开 始演练,我们现在建立一条到远程主机 guantouping 上端口 7001 的隧道,在 guantouping 上可以用 nc -l -p 7001 localhost 这条命令建立一个监听本地到端口 7001 的连接,这样确保无法从其他机器访问这台主机的端口,只能在 guantouping 这台主机上用 telnet localhost 7001 来连接。现在我的机器 IP 是 192.168.6.25,如果直接用命令 telnet guantouping 7001 访问的话,那么在主机 guantouping 上会看到这样的提示:

[taylor@guantouping taylor]$ nc -l -p 7001 localhost
invalid connection to [192.168.6.200] from (UNKNOWN) [192.168.6.25] 1926

在这个配置面板上, Source port 上填写 8080,也就是我们要通过本地的 8080 端口来进入 SSH 隧道, Destination 这里填上 127.0.0.1:7001,就表示被登录的主机 guantouping 访问该主机本地的 127.0.0.1:7001 这个端口。正常登录到主机 guantouping 以后,SSH 隧道就建立好了。在我的机器 192.168.6.25 上输入命令 telnet localhost 8080,输入一些东西,就会在 guantouping 上看到有响应。在这里我用的是 nc,看起来方便一点,telnet 也是一样的。

这 就是正向 SSH 隧道的一个例子,大家实地操作几次也就会明白了。最上面有个复选框是“Local ports accept connections from other hosts”,这个选项的作用是允许其他主机连接你机器上的隧道入口,默认情况下建立好隧道以后,只允许本地链接。只有选中这个复选框才允许其他主机连接 你的本地隧道入口。

象特洛伊木马一样建立一条 SSH 反向隧道

下面要说的就是选中单选按钮 Remote 后建立的反向 SSH 隧道,这样的隧道做什么用呢?一般防火墙都是允许从内往外链接,而不允许从外到内的链接,除非在防火墙上做好nat或端口转发。现在,你在防火墙的内部, 但是又想让外面的人链接到你的机器上。防火墙厚厚的城门紧闭,外面的人进不来,只有你能从里面打开这扇防护严密的大门,就像一个特洛伊木马一样,你主动连 接出去建立一个反向的 SSH 隧道,然后外面的人就可以通过这个反向的 SSH 隧道轻松突破防火墙链接到的你的本地机器。看下面这个图:

在 Source port 这里填写 8080,也就是隧道的入口是端口8080,Destination 这里填写 localhost:7001,也就是隧道的出口是本地的 7001 端口,下面的单选按钮要选中 Remote,表示建立的隧道是个反向隧道,填写完毕别忘记点 Add 按钮,在上面就可以看到显示的是 R8080 localhost:7001。成功登录远程主机 guantouping 后,反向隧道就建立好了。在远程主机 guantouping 上输入命令 telnet localhost 8080 就可以连接到你的本地端口7001。

哈 哈,这样一个特洛伊木马般的反向 SSH 隧道就建立完毕了。我们在远程主机上连接 8080 端口,其实就连接到了我们本地机器的7001 端口了。上面共有两个复选框,我们提到了一个,已经说了,选中以后就允许其他机器连接隧道入口了。那第二个“Remote ports do the same (SSH-2 only)”,则是给反向隧道使用的,也就是说远程主机的那个反响隧道入口也做同样的事情,也就是允许其他机器连接远程主机上的反向隧道入口,不过一般情 况下这个选项都不会起作用的 ^_^。

把 PuTTY 作为一个安全的代理服务器来使用

这个简单,在 Source port 那里填写上 1080,Destination 这里空下不填,选中下面的 Dynamic,最后别忘了点 Add 按钮。

登录远程主机后,一个代理服务器就建立好了,这个代理服务器的地址就是 localhost:1080,还是加密的哦。据说国外某著名的主机供应商就提供远程的 SSH 链接,通过这个方法我们就建立了一个加密的 socks5 代理,可以轻松绕过万恶的 GFW 去拥抱 Wikipedia,波~~~,来一口。

设置 PuTTY 的默认设置

每次登录主机,无一例外的修改字体,修改字符集,修改窗口的大小,指定私钥文件,允许 X11 转发,……
几台主机还好说,几十个上百个主机这样三天两头的设置也会让唐僧烦了的。
选中一个先前配置好的会话,点 Load 按钮。

然后修改Saved Sessions会话名称 和 Host Name 这里的主机地址,点Save

如果在 Saved Sessions 这里和上面的 Host Name 清空,点 Save 按钮,就可以把设置保存为默认设置。

备份 PuTTY 的设置

用 PuTTY 最不爽的就是,它把所有的设置都保存到注册表了,本来这不是什么问题。但是难免会重装一下机器,用下面的命令可以备份 PuTTY 的所有设置

regedit /e PuTTY.config.reg “HKEY_CURRENT_USER\Software\SimonTatham\PuTTY”

删除 PuTTY 的设置

如果只是在其他机器上临时用了一个 PuTTY,用完以后想删除 PuTTY 的配置,就在控制台里输入如下的命令:

putty.exe -cleanup

用 PuTTYgen 来生成密钥,以后可以不用密码登录服务器了

PuTTYgen 是密钥生成器,用来生成一对公钥和私钥供 PuTTY、PSCP、Plink、Pagent 来使用。
直接运行 PuTTYgen 可以看到如下的界面。

点击 Generate 按钮就开始生成一个公钥和私钥对,生成完毕后,点下面的 Save private key 就可以把私钥保存起来,扩展名是 .ppk 的文件。
Load 按钮可以把先前保存的私钥重新打开,然后做些修改,比如修改注释和私钥口令,或者把 PuTTY 格式的私钥转换为 OpenSSH 格式的。

开始用 PuTTYgen 创建密钥

单击 Generate 按钮,然后你会看到进度条上面有个提示“Please generate some radomness by moving the mouse over the blank area.”,意思就是让你用鼠标在空白区域随机移动。随着鼠标在空白区域的移动,进度条会一直走下去。停止移动鼠标,进度条也就停止了。那我们就移动鼠 标,直到进度条走满为止。

等进度条走完之后,会出现下面的界面

最上面那个大大的只读文本框里面是公钥,用来保存到 OpenSSH 的 authorized_keys 文件中,这个文件中的每一行都是一个公钥。默认情况下,这个文件位于 Linux 用户主目录的 .ssh/ 子目录中,如果文件和目录都不存在,可以直接创建。
但 是创建的文件、目录和用户主目录($HOME, $HOME/.ssh, $HOME/.ssh/authorized_keys)的权限有个限制就是对除了本帐户的其他所有帐户都要求是只读的,否则的话,即使公钥、私钥都匹配 无误,也是无法登入系统的。这是 SSH 服务器的一个安全要求,因为如果别的帐户可以修改你的 authorized_keys 的话,恶意的增加一个公钥,那对方不用你的帐户口令也能以你的帐户登入系统了。对于一些特殊要求,你可以在 SSH 服务器的配置文件 sshd_config 中用指令

StrictModes no

来取消这个限制。在 sshd_config 的帮助手册中可以看到

     StrictModes
Specifies whether sshd should check file modes and ownership of
the user’s files and home directory before accepting login.  This
is normally desirable because novices sometimes accidentally
leave their directory or files world-writable.  The default is
“yes”.

小技巧:每次修改 authorized_keys 这个文件时,你可以用如下的命令来修改,确保所有的文件属性和权限无误

mkdir -p $HOME/.ssh && touch $HOME/.ssh/authorized_keys \
&& chmod go-w $HOME $HOME/.ssh $HOME/.ssh/authorized_keys && vim $HOME/.ssh/authorized_keys

还有一个要强调的是那个 Key comment,这是密钥的注释,一定要修改。因为这个密钥是给自己用的,所以最起码要输入自己的名字,用默认的注释很容易和其他人的密钥混淆的。如果担 心自己的密码忘记了,可以在后面加上密码提示,当然了,不要让别人用注释猜出你的密钥口令。比如,我可以把注释修改为

ChaiFeng [20061120] w.z.

后面的 w.z. 就是我的密码提示,能猜出来么?呵呵

输入注释,上面的公钥也会随之发生变化。
现在最重要的是,输入自己的密钥口令。就是 Key passphrase 和 Confirm passphrase 这个两个输入框。
如果不输入口令,直接保存私钥会看到这个提示。为了安全起见还是输入口令吧,要不任何人得到这个私钥都可以不用口令登入系统了。

最后单击 Save private key 来保存私钥吧,保存到自己认为安全的地方,比如存放到私人的 USB 闪存盘上。需要登录时,插上 USB 闪存盘。登录完毕后就可以把 USB 闪存盘取下来,哈哈,这样子就比较安全了。
大 家也注意到了,还有个 Save public key 按钮,这个是保存 SSH2 格式的公钥,有些 SSH 服务器要求用这种格式的公钥文件。一般情况下,我们是不需要的,所以这里也就保存了。以后还想的话,就用 PuTTYgen 把私钥 Load 出来,然后再保存也可以。

用密钥登录服务器的流程

上面杂七杂八的说了一堆创建密钥时的事情,大家会不会已经有些乱了呢?我把这个过程再罗列一遍:

  1. 如果没有公钥/密钥对,就用 PuTTYgen 创建一个,已经有了就可以忽略这一步。一个公钥/密钥对可以用在不同的服务器上,所以也不需要重复创建,关键要有足够强健的密码和安全的存放。
  2. 象先前一样输入帐户名和口令登录到主机上。
  3. 输入如下命令,来编辑 authorized_keys 文件mkdir -p $HOME/.ssh && touch $HOME/.ssh/authorized_keys \&& chmod go-w $HOME $HOME/.ssh $HOME/.ssh/authorized_keys && vim $HOME/.ssh/authorized_keys
  4. 把这个文本框里的公钥粘贴到 vim 中去,需要说明几点:这个文本框里的内容是一行的,粘贴到 vim 中时,别忘了按字母 o 这个键,否则的话,粘贴进去后,开头的 ssh-rsa 会变成 sh-rsa,为什么呢?哈哈,想想吧。为什么不按字母键 i 呢?这个在 vim 中不就是插入么?原因是我很懒,按字母 o,我可以节省一次按回车键。虽然按大写 O 也行,那我不是还得再按一下 Shift 键么?别 忘了,在 PuTTY 中默认的粘贴可是按鼠标右键哦,然后按一下 ESC 键,然后输入 :wq 保存退出,等等,大家先别着急的输入 :wq,既然输入冒号还得按下 Shift 键,那我们就干脆直接两下大写的字母 Z,也就是 ZZ。怎么样?vim 也一样保存退出了吧。这次又节省了一次按键和两次寻找字母的移动,把懒得优良传统再一次在实践中发扬光大。
  5. 如果已经有了私钥,第4步里的那个公钥忘记保存了,就用 PuTTYgen 把这个私钥 Load 上去,然后重新复制一下公钥吧。
  6. 在 PuTTY 的配置 Connection->SSH->Auth 这里面,指定上私钥,然后记得保存 Session,以后就不需要重复这一步了。
  7. 最好也指定上自动登录的用户名,还记得这里吗?
  8. 开始登录吧,这次你会看到一个不同于以往的登录提示现 在输入的口令可不是主机上这个账户的口令了,而是先前创建的这个密钥的口令。以后不管这个账户的口令是什么,即使再复杂,也和我们没关系了。只要这个账户 的 $HOME/.ssh/authorized_keys 文件中,有我们的公钥,我们就随时用匹配的私钥都可以登录了。配合后面提到的 Pagent,我们连输入密钥口令这一步也可以忽略过去。
  9. 登录成功了,别忘了按 Ctrl+d 注销哦。

以后这些步骤就不需要再重复了,只需要打开 PuTTY 后,双击一下保存的会话名称,输入密钥口令。

Pagent 加载密钥,每次开机后只需要输入一次密钥口令

终于轮到 Pagent 出场了,双击一下 Pagent.exe,嗯,没反应?再双击一下,咦?出来个提示,说已经运行了。

看看右下角吧,在这里呢

双击一下 Pagent 的图标,出来这样一个界面。很简洁的,Add Key 是添加私钥,Remove Key 是把选中的私钥从 Pagent 中卸载了。

好,现在单击 Add Key 按钮添加私钥,我把这个演示用的私钥保存到 C:\ 了

然后会出现输入密钥口令的对话框,输入正确的密钥后,单击 OK

这时,在 Pagent 的窗口中就能看到我们的私钥已经装载上去了。

现在打开 PuTTY,选择先前保存的 Session,双击一下。只要自动登录用户名设置上,主机上改帐户的 authorized_keys 文件里也有匹配的公钥。哈哈,发现没有?完全不需要口令,我们已经登录到系统了。
在 Pagent 的图标上点右键,也可以快捷的选择已经保存的会话。

建 议大家把 Pagent 放到启动组里面,这样每次一开机,Pagent 自动运行,然后我们只需要把私钥装载一下,然后我们就可以一直享受自动登录系统的乐趣了。再配合上以后会讲到的 Plink、PSCP 这些,我们可以实现很多工作的自动化进行。完全不需要每次输入用户名、口令、输入又长又多的命令,再做一些烦躁的文件备份,最后还得记得注销系统,难道不 觉得麻烦么?这一切烦恼很快就会远离我们了,继续往下看吧。

用 SSH 来传输文件

PuTTY 提供了两个文件传输工具

  • PSCP (PuTTY Secure Copy client)
  • PSFTP (PuTTY SFTP client)

PSCP 通过 SSH 连接,在两台机器之间安全的传输文件,可以用于任何 SSH(包括 SSH v1、SSH v2) 服务器。
PSFTP 则是 SSH-2 中新增的特性,使用的是新的 SFTP 协议,使用上与传统的 FTP 类似。事实上 PSCP 如果发现 SFTP 可用,PSCP就会使用 SFTP 协议来传输文件,否则还是 SCP 协议。PSFTP 与 PSCP 相比,PSFTP 的优点是可以与服务器进行交互,遍历服务器上的文件系统,在一个会话中上传或下载多个文件。而 PSCP 只能一次传输一个文件,传输完毕后立刻终止会话。

PSCP 的使用

在控制台直接执行 pscp 可以看到帮助

C:\>pscp
PuTTY Secure Copy client
Release 0.58
Usage: pscp [options] [user@]host:source target
pscp [options] source [source…] [user@]host:target
pscp [options] -ls [user@]host:filespec
Options:
-V        print version information and exit
-pgpfp    print PGP key fingerprints and exit
-p        preserve file attributes
-q        quiet, don’t show statistics
-r        copy directories recursively
-v        show verbose messages
-load sessname  Load settings from saved session
-P port   connect to specified port
-l user   connect with specified username
-pw passw login with specified password
-1 -2     force use of particular SSH protocol version
-4 -6     force use of IPv4 or IPv6
-C        enable compression
-i key    private key file for authentication
-batch    disable all interactive prompts
-unsafe   allow server-side wildcards (DANGEROUS)
-sftp     force use of SFTP protocol
-scp      force use of SCP protocol

C:\>

可以看出 PSCP 的使用是很简单的,把常用的几个选项说一下:

  • -q 安静模式,传输文件时什么也不显示,否则会显示出文件的传输进度,默认是关闭的
  • -P port 指定服务器的 SSH 端口,注意这个是大写字母 P,默认是 -P 22,如果主机的 SSH 端口就是 22,就不用指定了
  • -l user 指定以哪个用户的身份登录主机,如果没有指定,则 PSCP 会在 PuTTY 保存的同名 Session 中获得默认的用户名称。用户名称也可以和主机名称写在一起,用 @ 分割开,比如:username@server
  • -pw passwd 指定登录时所用的口令为 passwd
  • -i keyfile 就是指定登录时所用的密钥文件
  • 最 后面指定的主机名也可以是 PuTTY 中保存的 Session 名称。比如我们在 PuTTY 中保存了一个名为 foobarserver 的会话,而我们所在的网络又的确没有名为 foobarserver 的主机名称。而在这个 foobarserver 会话中保存的主机名称是 demo-server,保存的自动登录的用户是 taylor。那么用命令 就把本地的 c:\autoexec.bat 复制到了主机 demo-server 上的用户 taylor 所在的主目录下的 backup 子目录中(这个路径可能是 /home/taylor/backup

    pscp c:\autoexec.bat foobarserver:backup/

所以 PSCP 大致用法的例子就是:
pscp -P 22 -i c:\path\your-private-key.ppk -C username@server:/remote/path/
下面还是用一些实例来说明会比较简单一些:
把本地的 C:\path\foo.txt 复制到远程主机 192.168.6.200 的 /tmp 目录下

pscp c:\path\foo.txt 192.168.6.200:/tmp

把本地的 C:\path\foo.txt 复制到主机 192.168.6.200 的 /tmp 目录下,但是以主机上的用户 taylor 的权限执行

pscp c:\path\foo.txt taylor@192.168.6.200:/tmp

或者是

pscp -l taylor c:\path\foo.txt 192.168.6.200:/tmp

把本地的 C:\path\foo.txt 传送到主机 192.168.6.200 的 /tmp 目录下,但是主机的 SSH 端口是 3122

pscp -P 3122 c:\path\foo.txt 192.168.6.200:/tmp

把本地的 C:\path\foo.txt 复制到主机 192.168.6.200 的用户 taylor 的主目录下

pscp c:\path\foo.txt taylor@192.168.6.200:.

把主机 192.168.6.200 上的用户 taylor 主目录下的所有 *.tgz 文件拷贝到本地的 c:\backup 目录中,如果 SSH 版本是 SSH v1,那这个命令就会出错。

pscp taylor@192.168.6.200:*.tgz c:\backup

再来看看 PSFTP

在控制台执行命令 psftp -h,可以得到 psftp 的帮助

C:\>psftp -h
PuTTY Secure File Transfer (SFTP) client
Release 0.58
Usage: psftp [options] [user@]host
Options:
-V        print version information and exit
-pgpfp    print PGP key fingerprints and exit
-b file   use specified batchfile
-bc       output batchfile commands
-be       don’t stop batchfile processing if errors
-v        show verbose messages
-load sessname  Load settings from saved session
-l user   connect with specified username
-P port   connect to specified port
-pw passw login with specified password
-1 -2     force use of particular SSH protocol version
-4 -6     force use of IPv4 or IPv6
-C        enable compression
-i key    private key file for authentication
-batch    disable all interactive prompts

C:\>

用法与 PSCP 大同小异,虽然有个 -load 选项,其实这个没啥用,后面用主机名的时候,与 PSCP 一样直接用上会话名称就可以了。
用 PSFTP 登录到服务器上以后,操作与 FTP 差不多,这里简单的说一下吧:

  • open 登录主机open [username@]<sessname|hostname|ip> [port]比如:
    • open taylor@demo-server 3022
      就是以用户 taylor 的身份,登陆到主机 demo-server 上,SSH 端口是 3022
    • open demo-server
      登陆 demo-server,这里的 demo-server 可以是PuTTY 中已经保存的会话名称,也可以是主机的名称,如果主机名称与会话名称相同,以会话名称为准。
  • close 关闭 SFTP 连接这个没啥说的,close 就关闭了 SFTP 连接
  • quit 结束本次的 SFTP 会话也没啥用法,就是关闭了 PSFTP 这个程序
  • help [command] 帮助直接打 help 就可以看到帮助指令,后面指定上 一个命令就可以查看该命令的帮助,比如: help open
  • cd [directory] 改变当前目录
  • pwd 察看当前目录
  • lcd [directory] 改变本地目录
  • lpwd 察看本地当前目录
  • get [-r] <filename|directory> 从服务器下载一个文件/目录,这个命令不能用通配符,参数 -r 可以递归下载整个目录
  • put [-r] <filename|directory> [dest] 把文件/目录上传到服务器,这个命令不能用通配符,参数 -r 可以递归上传整个目录
  • mget [-r] <filename|directory> 从服务器下载一批文件/目录,可以用通配符,-r 的含义与 get 一样
  • mget [-r] <filename|directory> [dest] 把一批文件/目录上传到服务器,可以用通配符,-r 的含义与 put 一样
  • reget [-r] <filename|directory> 从服务器续传下载一个文件/目录,这个命令不能用通配符,-r 的含义与 get 一样
  • reput [-r] <filename|directory> [dest] 把一批文件/目录续传上传到服务器,这个命令不能用通配符,-r 的含义与 put 一样
  • dir [directory] 列目录
  • ls 和 dir 一样
  • chmod [file|directory] 改变文件的权限,与 Unix 的 chmod 命令类似
  • del <filename> 删除文件,要注意的是 del 只能删除文件
  • rm 与 del 一样
  • mkdir <new-directory-name> 创建一个目录
  • rmdir <directory> 删除一个空目录,只有空目录才可以被删除
  • mv <source-file|source-directory> <dest-file|dest-directory> 改名/移动。如果源和目的都是文件或目录,则是改名。如果目的是目录的话,则是移动。
  • ! 在本地命令前加一个感叹号,就可以直接执行

其他可选的 SFTP 客户端

FileZilla : http://filezilla.sf.net/
WinSCP : http://www.winscp.net/

用 Plink 更方便快捷的执行远程主机上的命令

Plink 是 PuTTY 的命令行连接工具,主要用于自动化工作的处理。
直接在控制台执行 plink,可以看到 Plink 的帮助

C:\>plink
PuTTY Link: command-line connection utility
Release 0.58
Usage: plink [options] [user@]host [command]
(“host” can also be a PuTTY saved session name)
Options:
-V        print version information and exit
-pgpfp    print PGP key fingerprints and exit
-v        show verbose messages
-load sessname  Load settings from saved session
-ssh -telnet -rlogin -raw
force use of a particular protocol
-P port   connect to specified port
-l user   connect with specified username
-batch    disable all interactive prompts
The following options only apply to SSH connections:
-pw passw login with specified password
-D [listen-IP:]listen-port
Dynamic SOCKS-based port forwarding
-L [listen-IP:]listen-port:host:port
Forward local port to remote address
-R [listen-IP:]listen-port:host:port
Forward remote port to local address
-X -x     enable / disable X11 forwarding
-A -a     enable / disable agent forwarding
-t -T     enable / disable pty allocation
-1 -2     force use of particular protocol version
-4 -6     force use of IPv4 or IPv6
-C        enable compression
-i key    private key file for authentication
-m file   read remote command(s) from file
-s        remote command is an SSH subsystem (SSH-2 only)
-N        don’t start a shell/command (SSH-2 only)

C:\>

看上去 Plink 的使用方法、参数与PSCP、PSFTP都很类似。

  • -P port 指定服务器的 SSH 端口,注意这个是大写字母 P,默认是 -P 22,如果主机的 SSH 端口就是 22,就不用指定了
  • -l user 指定以哪个用户的身份登录主机,如果没有指定,则 PSCP 会在 PuTTY 保存的同名 Session 中获得默认的用户名称。用户名称也可以和主机名称写在一起,用 @ 分割开,比如:username@server
  • -pw passwd 指定登录时所用的口令为 passwd
  • -i keyfile 就是指定登录时所用的密钥文件
  • -m file 如果执行的命令很多的话,可以把命令写到文件中,然后用这个参数来指定

还是用一些实际的例子来说明一下 Plink 吧
还记得前面说到 PuTTY 的自动执行命令那个配置么?在说到那个配置的时候,我们演示了一个简单的 Tomcat 重新启动的命令,这个命令是要写在 PuTTY 的 Remote command 里面去。现在我们用 Plink 来实现同样的功能:
假设连接的主机是 192.168.6.200,SSH 的端口是 3022,用户是 taylor:

plink -P 3022 taylor@192.168.6.200 export CATALINA_HOME=”~/apache-tomcat-5.5.17″;export JAVA_HOME=”~/jdk1.5.0_07″;export PATH=$JAVA_HOME/bin;$PATH ; cd $CATALINA_HOME/bin;./shutdown.sh;./startup.sh;tail -f $CATALINA_HOME/logs/catalina.out

如果在 PuTTY 中保存了一个名为 192.168.6.200 的会话,注意,这个会话的名称与主机 IP 一样,在会话中已经正确保存了端口 3022,指定了默认的用户是 taylor,现在这个命令就可以简化为:

plink 192.168.6.200 export CATALINA_HOME=”~/apache-tomcat-5.5.17″;export JAVA_HOME=”~/jdk1.5.0_07″;export PATH=$JAVA_HOME/bin;$PATH ; cd $CATALINA_HOME/bin;./shutdown.sh;./startup.sh;tail -f $CATALINA_HOME/logs/catalina.out

用 date 命令查看一下主机上的时间,并且格式化输出:

plink 192.168.6.200 date “+%F %T”

大家实际执行一下命令看看,会发现,这个命令并没有返回我们期望的结果,而是返回了一个错误:

C:\>plink 192.168.6.200 date “+%F %T”
date: too many non-option arguments: %T
Try `date –help’ for more information.

可是在服务器上直接执行命令 date “+%F %T”,的确是正确无误的,哪里出了问题呢?这是因为Windows的控制台会把两个双引号之间的字符串作为一个参数传递给被执行的程序,而不会把双引号也传递给程序。我们做这样一个小小的实验来说明一下这个问题:
比 如在 c:\tmp 文件夹里建立三个文件夹,名称分别为:”foo”、”bar”、”foo bar”。然后在 foo 这个文件夹里面建立一个名为“foo.log”的空文件,在“bar”这个文件夹里建立一个名为“bar.log”的空文件,在“foo bar”这个文件夹里建立一个名为“foo-bar.log”的空文件。
然后在控制台下进入 c:\tmp 这个文件夹,执行如下命令:

dir foo bar

结果是列出“foo bar”这个文件夹里的内容,还是分别列出“foo”和“bar”文件夹里的东西呢?正确答案是后者。
要想正确列出“foo bar”文件夹里的东西,就需要用双引号把”foo bar”引起来

C:\tmp>dir foo bar
Volume in drive C is System
Volume Serial Number is 9C51-A51C

Directory of C:\tmp\foo

2006-11-22  09:48    <DIR>          .
2006-11-22  09:48    <DIR>          ..
2006-11-16  11:58                 0 foo.log
1 File(s)              0 bytes

Directory of C:\tmp\bar

2006-11-22  09:48    <DIR>          .
2006-11-22  09:48    <DIR>          ..
2006-11-16  11:58                 0 bar.log
1 File(s)              0 bytes
2 Dir(s)   1,107,345,408 bytes free

C:\tmp>dir “foo bar”
Volume in drive C is System
Volume Serial Number is 9C51-A51C

Directory of C:\tmp\foo bar

2006-11-22  09:48    <DIR>          .
2006-11-22  09:48    <DIR>          ..
2006-11-16  11:58                 0 foo-bar.log
1 File(s)              0 bytes
2 Dir(s)   1,107,345,408 bytes free

C:\tmp>

说到这里,就会明白上面的那个命令 plink 192.168.6.200 date “+%F %T” 其实在主机上执行的真实命令是 date +%F %T,而不是命令行中指定的 date “+%F %T”。不过还好,Windows 的控制台可不认得单引号,所以上面那个命令的正确用法应该是:

c:\>plink 192.168.6.200 date ‘+%F %T’
2006-11-22 09:39:57

我经常需要登录到服务器上把 ADSL 重新拨号,可以把下面的命令写到一个文本文件中,比如保存到了 C:\adsl-restart.command.txt

echo “stoping…”
/sbin/adsl-stop
echo “starting…”
/sbin/adsl-start
echo “done.”
/sbin/adsl-status

然后执行如下命令:

plink -m c:\adsl-restart.command.txt root@192.168.6.251

我经常要查看 Tomcat 的运行日志

plink taylor@192.168.6.200 tail -f ~/apache-tomcat-5.5.17/logs/catalina.out

每天都要看服务器上的剩余空间,就用这个命令:

plink taylor@192.168.6.200 df -k

假设 http://www.cnblogs.com/tippoint/admin/www.chaifeng.com 连接着另外一个网段 10.204.26.0,有台内网IP 为 10.204.26.21 的 Solaris 8主机只能用 telnet 登录,为了防止被监听,我们可以用 Plink 建立一个隧道,隧道开放 120 秒钟,如果隧道没有被使用,就自动断开连接,然后我们在本地就可以用命令 telnet localhost 2623 的安全登录那台 Solaris 8 主机了。

plink -L 2623:10.204.26.21:23 http://www.cnblogs.com/tippoint/admin/www.chaifeng.com sleep 120

在主机 http://www.cnblogs.com/tippoint/admin/www.chaifeng.com 上正在运行着 tor,默认的监听地址是 127.0.0.1:9050,用 Plink 建立一个隧道,然后浏览器上配置代理服务器为 127.0.0.1,端口是 9050,这样就能够安全的使用 tor 代理了,不用担心从我们的机器到主机 http://www.cnblogs.com/tippoint/admin/www.chaifeng.com 有被监听的可能了。

plink -C -N -L 9050:127.0.0.1:9050 taylor@http://www.cnblogs.com/tippoint/admin/www.chaifeng.com

结合上 PSCP 我们还可以完成文件的每天备份

plink taylor@192.168.6.200 tar jcf $(date ‘+documents.%F.tar.bz2’) ~/documents
pscp taylor@192.168.6.200:$(date ‘+documents.%F.tar.bz2’) c:\backup\
plink taylor@192.168.6.200 rm -f $(date ‘+documents.%F.tar.bz2’)

如果把这些常用的操作写成批处理文件,到时候要重启一下 Tomcat,或者马上察看一下 Tomcat 日志,再或者只是要把 ADLS 重新拨号以下,只需要用鼠标一双击这个批处理文件,稍等一下就自动完成了。不比你打开 PuTTY,登录到服务器上,然后再一个一个的执行命令,最后还得注销来的方便快捷么?再懒一些,把自动备份的批处理放到计划任务里面,每天定时完成,哈 哈,有时间上网找些好玩的东西了,不用每天忙于这些繁杂重复的命令中了。

用假象去迷惑敌人

如果我说 Google 的服务器也开放了 SSH,但是只有特定的 IP 可以连接上去,不信么?(声明:下面的图片都未经修改,我以 Google 的名义发誓,绝对没有 PS)


知道是怎么回事么?

FAQ(常见问题)

我在 PuTTY 官方网站下载的,可是执行 PuTTY、Pagent、PuTTYgen 时总是出错,而命令行执行的这几个却没问题

这种情形我也碰到过,一个解决的办法就是去下载最新版,或许你碰巧下载的是旧版本。另外一个解决办法就是,创建三个扩展名为 .manifest 的文本文件,然后把这三个文件复制到 PuTTY 的目录中,文件内容分别如下:
把下面的内容复制到记事本中,文件名保存为:PAGEANT.exe.manifest

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>
<!– This is present purely to make Visual Styles in XP work better.
See 20020104174954.A12067@imsa.edu. –>
<assembly xmlns=”urn:schemas-microsoft-com:asm.v1″ manifestVersion=”1.0″>
<assemblyIdentity
type=”win32″
name=”Pageant”
version=”0.0.0.0″ processorArchitecture=”x86″/>
<dependency>
<dependentAssembly>
<!– Load Common Controls 6 instead of 5 to get WinXP native-
looking controls in the client area. –>
<assemblyIdentity type=”win32″
name=”Microsoft.Windows.Common-Controls”
version=”6.0.0.0″
publicKeyToken=”6595b64144ccf1df”
language=”*”
processorArchitecture=”x86″/>
</dependentAssembly>
</dependency>
</assembly>

把下面的内容复制到记事本中,文件名保存为:PUTTY.exe.manifest

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>
<!– This is present purely to make Visual Styles in XP work better.
See 20020104174954.A12067@imsa.edu. –>
<assembly xmlns=”urn:schemas-microsoft-com:asm.v1″ manifestVersion=”1.0″>
<assemblyIdentity
type=”win32″
name=”PuTTY”
version=”0.0.0.0″ processorArchitecture=”x86″/>
<dependency>
<dependentAssembly>
<!– Load Common Controls 6 instead of 5 to get WinXP native-
looking controls in the client area. –>
<assemblyIdentity type=”win32″
name=”Microsoft.Windows.Common-Controls”
version=”6.0.0.0″
publicKeyToken=”6595b64144ccf1df”
language=”*”
processorArchitecture=”x86″/>
</dependentAssembly>
</dependency>
</assembly>

把下面的内容复制到记事本中,文件名保存为:PUTTYGEN.exe.manifest

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>
<!– This is present purely to make Visual Styles in XP work better.
See 20020104174954.A12067@imsa.edu. –>
<assembly xmlns=”urn:schemas-microsoft-com:asm.v1″ manifestVersion=”1.0″>
<assemblyIdentity
type=”win32″
name=”PuTTYgen”
version=”0.0.0.0″ processorArchitecture=”x86″/>
<dependency>
<dependentAssembly>
<!– Load Common Controls 6 instead of 5 to get WinXP native-
looking controls in the client area. –>
<assemblyIdentity type=”win32″
name=”Microsoft.Windows.Common-Controls”
version=”6.0.0.0″
publicKeyToken=”6595b64144ccf1df”
language=”*”
processorArchitecture=”x86″/>
</dependentAssembly>
</dependency>
</assembly>

屏幕输出太快了,怎么能暂停一下?

Ctrl+S 快捷键可以暂停终端,Ctrl+Q 恢复。

怎么翻页?

Shift+PageUp/PageDown 一页一页的翻,Ctrl+PageUp/PageDown 则是一行一行的。

不是说 PSCP 一次只能传输一个文件么?为什么我发现能传输很多个?

那是因为 PSCP 发现 SFTP 协议可用,优先使用 SFTP 协议来传输文件

为什么执行了 pscp、psftp、plink 这些命令总是说错误的命令呢?

应该把 PuTTY 所在的路径添加到 PATH 环境变量中。你可以编辑 c:\autoexec.bat 这个文件,在最后增加一行,把 c:\path\to\putty 换成你的真实路径

set PATH=c:\path\to\putty;%PATH%

from http://www.cnblogs.com/hnrainll/archive/2011/08/11/2135315.html

[转]Pentadactyl,让firefox按vim习惯运行的插件

Pentadactyl

2011-02-05 22:37:59 /Mozilla/Firefox

鼓捣了两个小时Pentadactyl,真是个叫人语无伦次的东西,硬是把我从Chromium又拉回到Firefox了。

Pentadactyl是源于Vimperator的一个Firefox插件,但是装上这个插件之后Firefox就不叫Firefox了叫Vim……

这个插件有一个缺点是浪费鼠标。

前奏

装了这个插件后启动Firefox时界面可能会有很大变化,熟悉的各种XX栏可能都会消失。恢复的办法是

1
set go+=mBT

这样子可能会熟悉一些。不过还是建议用

1
set go-=mBT

让它们消失吧。一旦你习惯了Pentadactyl你不会想看见它们的。

下文中<C-x>表示Ctrl+x,<A-x>表示Alt+x,<S-x>表示Shift+x,<M-x>表示Meta+x。

使用这个插件需要一定的Vim基础。最起码的,要知道模式的概念以及甩Esc可以回到Normal模式。还要知道:help是个有用的命令。

第一课 导航

以下是有关导航的基本命令,有了这些就可以随心所欲浏览页面了。

页面导航

  • h,j,k,l:四大金刚
  • <C-d>:下半页
  • <C-u>:上半页
  • <C-f>/<Space>:下一页
  • <C-b>/<S-Space>:上一页
  • gg:页首
  • G:页尾
  • [num]gg/[num]G/[num]%:跳至页面num%处

标签导航

  • <C-n>/gt:下一个标签
  • <C-p>/gT:上一个标签
  • g0/g^:第一个标签
  • g$:最后一个标签
  • <C-6>:在当前标签和最近浏览的非当前标签之间切换

历史记录导航

  • H/<C-o>:在历史记录中后退
  • L/<C-i>:在历史记录中前进

第二课 网页的打开与关闭

要打开一个网页需要进入Command-line模式,用过Vim的一定不会陌生,就是按下冒号:后的那个模式。在Command-line模式下有如下基本命令:

  • o/O:在当前标签打开
  • t/T:在新标签打开
  • w/W:在新窗口打开

其中小写与大写的区别是,小写会直接执行,大写会将当前URL作为参数显示出来,可以修改后回车确认再执行。

要关闭一个标签,在Normal模式下:

  • d/D:关闭当前标签

区别是,用d关闭后选择右边的标签,用D关闭后选择左边的标签。

还有一些常用的命令:

  • u:打开最近关闭的标签
  • <C-c>:停止载入
  • r/R:重新载入当前页面(R无视cache)
  • gh:回主页
  • gu:打开上级目录
  • gU:打开根目录

要退出Firefox怎么办呢?有两种方法:

  • ZQ:退出Firefox
  • ZZ:保存已打开的页面并退出Firefox

第三课 页面控制

  • <C-g>:查看页面基本信息
  • g<C-g>:查看页面详细信息
  • gf:在页面和其源代码之间切换
  • gi:定位到最近输入的文本框。如果没有最近输入的文本框,则定位到第一个文本框
  • zi/+/zm:放大页面
  • zo/-/zr:缩小页面
  • zz:恢复页面至初始大小

区别是,zm和zr更狠。

  • y:复制当前URL到剪贴板
  • p/P:打开剪贴板中的URL(p=当前标签,P=新标签)

第四课 页面内容查找

和Vim中基本相同,也是用/和?

  • /:向前查找
  • ?:向后查找
  • n:查找下一个
  • N:查找上一个
  • *:向前查找当前光标下的单词
  • #:向后查找当前光标下的单词

第五课 页面导航进阶

现在我们来看如何打开网页中的链接。这需要进入Pentadactyl的Hint模式。有两种方法可以使用:

  • f/F:进入QuickHint模式(f=当前标签,F=新标签)
  • ;{mode}:进入extended hint模式(不同的{mode}会导致不同的结果)

最简单的,当前页面里有个链接,按下f键,链接上会出现数字,输入那个数字,就跳到那个链接去了。如果按下的是F键,则会在新标签中打开那个链接。如果按下的是;键,则还需要按下{mode},具体请参见help。

在学会了爬链接之后我们再熟悉一下标签之间的跳转(确切地说应该是buffer之间的跳转):

  • B:显示所有buffer
  • b:跳转到指定buffer

按下B键后可以看到所有的buffer,标记%的那个就是当前buffer,标记#的那个是alternate buffer。按下b键后会让你选择,你可以用数字或关键字跳转到指定buffer,也可以输入#跳转到alternate buffer。

第六课 书签

Pentadactyl支持Firefox的标准书签(Bookmarks)和自身特有的Quickmarks。

对Bookmarks的操作:

  • a:添加书签
  • A:添加/删除(Toggle)当前页面为书签
  • bmarks [url]:列出所有书签。若url不为空,列出(关键字)匹配url的书签
  • delbm [url]:删除(关键字)匹配url的书签。若url为空,删除当前页面为书签

对Quickmarks的操作:

  • M{a-zA-Z0-9}:添加当前页面到Quickmark
  • go{a-zA-Z0-9}:在当前标签页跳转到指定的Quickmark
  • go{a-zA-Z0-9}:在新标签页跳转到指定的Quickmark
  • qmarks [arg]:列出所有Quickmarks。若arg不为空,列出(关键字)匹配arg的Quickmarks
  • delqm {arg}:删除(关键字)匹配arg的Quickmarks

第七课 自定义键位映射

不爽的人各有各的不爽,不能自定义的工具不是好工具,是吧。

定义键位映射需要在Command-line模式下进行,需要的命令有:

  • map {lhs} {rhs}:定义键位映射
  • noremap {lhs} {rhs}:以-builtin方式定义键位映射
  • unmap {lhs}:取消键位映射
  • mapclear:清除键位映射

举个例子吧。J和K两个键位闲着也是闲着,不如用它们来翻页。那我就可以用

1
2
:map J <C-d>
:map K <C-u>

来定义两个映射。这样会比较保护小指一点吧。那么为什么需要noremap这个东西呢?看下面这个例子:

1
2
:map d D
:map D d

这个会怎么样呢?会让Firefox死翘翘呀!你按下d,它变成D,又变成d,又变成D……就死翘翘啦!正确的做法是:

1
2
:noremap d D
:noremap D d

这样子以-builtin方式定义,按下d,它变成D后就不再管其他的映射了,就不会出现死循环了。

Pentadactyl更强大的地方在于可以对不同模式进行不同的键位设定哦。Pentadactyl有如下几种主要的模 式:Normal(n),Visual(v),Insert(i),TextEdit(t),Command-line(c)。其实上面的四个命令都是针 对Normal和Visual模式的。要想定义其他模式下的键位映射,可以用如下格式的命令:

  • [n|v|i|t|c]map:(同上)
  • [n|v|i|t|c]noremap:(同上)
  • [n|v|i|t|c]unmap:(同上)
  • [n|v|i|t|c]mapclear:(同上)

功能都是一样的,所以就不说了。

第八课 保存设定

哎呀你不是已经退出了吧,退出的话刚才自定义的那些设定就都没有了啦!在退出之前要快快保存才是。保存的命令很简单:

  • mkp[!]:保存设定到mkpentadactylrc(!表示强制执行)

这个文件一般是$HOME/.mkpentadactylrc。这样子自己的设定可以统统保存和备份,万一到新机器上直接copy过来用就是了。

第九课 打开Firefox的对话框

到这里估计你已经习惯了Pentadactyl吧。不过有时候还是需要和Firefox打交道,比如设置个代理什么的。这时候有一个Command-line模式下的命令:

  • dia:打开对话框

输入:dia {name}就可以打开指定的对话框了。对于常用的对话框,还有更简单的命令,例如pref,addons等等。

到这里你应该发现很多命令都可以用Tab轮询吧……

第十课 实用技巧

写到这里主要内容就算是完成了。最后介绍一点使用技巧,因人而异,也许你会用的上。

  • 首先是gi的使用。这真的是个非常有用的命令,尤其是在搜索引擎上。你可以多按ESC使得页面停留在Normal模式下。当需要输入文字时按gi,就会自动定位到文本框了。
  • 用<C-n>/<C-p>翻页是一个比较好的选择。但是在Insert模式下(比如在文本框中输入文字的时候)这两个键位没有被定义。所以按<C-n>的时候会打开一个新窗口,太糟糕了。解决一下:
    1
    2
    :imap <C-n> <Esc>:tabnext<CR>
    :imap <C-p> <Esc>:tabprev<CR>
  • 想要快速搜索一个单词?只要在Firefox中设置好默认搜索引擎,按o键再输入那个单词就可以了。如果那个单词已经在剪贴板中,直接按p键更快。
  • 在浏览器中打字感到厌烦?尝试一下外部编辑器吧。在Insert模式下输入<C-i>可以打开指定的外部编辑器,以Vim为例,写好之后:wq退出即可。如果不想要这么麻烦,可以输入<C-t>进入内置的Vi模式,也很不错。
  • 看教程点Next是不是很罗嗦?有了Pentadactyl,你只需要按]]即可。同样的,[[相当于点击了页面中的Prev。来这里体验一下:http://docs.python.org/py3k/tutorial/modules.html
  • 修改nextpattern/previouspattern使之支持Google搜索结果的翻页:
    1
    2
    :set nextpattern=\s*下一页|下一张|下一篇|下页|后页\s*,^\bnext\b,\\bnext\\b,^>$,^(>>|»)$,^(>|»),(>|»)$,\\bmore\\b
    :set previouspattern=\s*上一页|上一张|上一篇|上页|前页\s*,^\bprev|previous\b,\\bprev|previous\\b,^<$,^(<<|«)$,^(<|«),(<|«)$
  • 看Blog翻页也很烦吧?试试<C-a>/<C-x>,它们会增减URL最后的数字,哈哈反正我用着是很有爽感啊。
  • 就像Vim一样,很多命令前面是可以加数字的。

from http://blog.cykerway.com/post/289

[转]Linux下使用sed编辑器详解

sed 编辑器是 Linux 系统管理员的工具包中最有用的资产之一,

因此,有必要彻底地了解其应用

Linux 操作系统最大的一个好处是它带有各种各样的实用工具。存在如此之多不同的实用工具,几乎不可能知道并了解所有这些工具。可以简化关键情况下操作的一个实用 工具是 sed。它是任何管理员的工具包中最强大的工具之一,并且可以证明它自己在关键情况下非常有价值。

sed 实用工具是一个“编辑器”,但它与其它大多数编辑器不同。除了不面向屏幕之外,它还是非交互式的。这意味着您必须将要对数据执行的命令插入到命令行或要处 理的脚本中。当显示它时,请忘记您在使用 Microsoft Word 或其它大多数编辑器时拥有的交互式编辑文件功能。sed 在一个文件(或文件集)中非交互式、并且不加询问地接收一系列的命令并执行它们。因而,它流经文本就如同水流经溪流一样,因而 sed 恰当地代表了流编辑器。它可以用来将所有出现的 “Mr. Smyth” 修改为 “Mr. Smith”,或将 “tiger cub” 修改为 “wolf cub”。流编辑器非常适合于执行重复的编辑,这种重复编辑如果由人工完成将花费大量的时间。其参数可能和一次性使用一个简单的操作所需的参数一样有限, 或者和一个具有成千上万行要进行编辑修改的脚本文件一样复杂。sed 是 Linux 和 UNIX 工具箱中最有用的工具之一,且使用的参数非常少。

sed 的工作方式

sed 实用工具按顺序逐行将文件读入到内存中。然后,它执行为该行指定的所有操作,并在完成请求的修改之后将该行放回到内存中,以将其转储至终端。完成了这一行 上的所有操作之后,它读取文件的下一行,然后重复该过程直到它完成该文件。如同前面所提到的,默认输出是将每一行的内容输出到屏幕上。在这里,开始涉及到 两个重要的因素—首先,输出可以被重定向到另一文件中,以保存变化;第二,源文件(默认地)保持不被修改。sed 默认读取整个文件并对其中的每一行进行修改。不过,可以按需要将操作限制在指定的行上。

该实用工具的语法为:

sed [options] ‘{command}’ [filename]

在这篇文章中,我们将浏览最常用的命令和选项,并演示它们如何工作,以及它们适于在何处使用。

替换命令

sed 实用工具以及其它任何类似的编辑器的最常用的命令之一是用一个值替换另一个值。用来实现这一目的的操作的命令部分语法是:

‘s/{old value}/{new value}/’

因而,下面演示了如何非常简单地将 “tiger” 修改为 “wolf”:

$ echo The tiger cubs will meet on Tuesday after school | sed

‘s/tiger/wolf/’

The wolf cubs will meet on Tuesday after school

$

注意如果输入是源自之前的命令输出,则不需要指定文件名—同样的原则也适用于 awk、sort 和其它大多数 Linux\\UNIX 命令行实用工具程序。

多次修改

如果需要对同一文件或行作多次修改,可以有三种方法来实现它。第一种是使用 “-e” 选项,它通知程序使用了多条编辑命令。例如:

$ echo The tiger cubs will meet on Tuesday after school | sed -e ‘

s/tiger/wolf/’ -e ‘s/after/before/’

The wolf cubs will meet on Tuesday before school

$

这是实现它的非常复杂的方法,因此 “-e” 选项不常被大范围使用。更好的方法是用分号来分隔命令:

$ echo The tiger cubs will meet on Tuesday after school | sed ‘

s/tiger/wolf/; s/after/before/’

The wolf cubs will meet on Tuesday before school

$

注意分号必须是紧跟斜线之后的下一个字符。如果两者之间有一个空格,操作将不能成功完成,并返回一条错误消息。这两种方法都很好,但许多管理员 更喜欢另一种方法。要注意的一个关键问题是,两个撇号 (‘ ‘) 之间的全部内容都被解释为 sed 命令。直到您输入了第二个撇号,读入这些命令的 shell 程序才会认为您完成了输入。这意味着可以在多行上输入命令—同时 Linux 将提示符从 PS1 变为一个延续提示符(通常为 “>”)—直到输入了第二个撇号。一旦输入了第二个撇号,并且按下了 Enter 键,则处理就进行并产生相同的结果,如下所示:

$ echo The tiger cubs will meet on Tuesday after school | sed ‘

> s/tiger/wolf/

> s/after/before/’

The wolf cubs will meet on Tuesday before school

$

全局修改

让我们开始一次看似简单的编辑。假定在要修改的消息中出现了多次要修改的项目。默认方式下,结果可能和预期的有所不同,如下所示:

$ echo The tiger cubs will meet this Tuesday at the same time

as the meeting last Tuesday | sed ‘s/Tuesday/Thursday/’

The tiger cubs will meet this Thursday at the same time

as the meeting last Tuesday

$

与将出现的每个 “Tuesday” 修改为 “Thursday” 相反,sed 编辑器在找到一个要修改的项目并作了修改之后继续处理下一行,而不读整行。sed 命令功能大体上类似于替换命令,这意味着它们都处理每一行中出现的第一个选定序列。为了替换出现的每一个项目,在同一行中出现多个要替换的项目的情况下, 您必须指定在全局进行该操作:

$ echo The tiger cubs will meet this Tuesday at the same time

as the meeting last Tuesday | sed ‘s/Tuesday/Thursday/g’

The tiger cubs will meet this Thursday at the same time

as the meeting last Thursday

$

请记住不管您要查找的序列是否仅包含一个字符或词组,这种对全局化的要求都是必需的。

sed 还可以用来修改记录字段分隔符。例如,以下命令将把所有的 tab 修改为空格:

sed ‘s// /g’

其中,第一组斜线之间的项目是一个 tab,而第二组斜线之间的项目是一个空格。作为一条通用的规则,sed 可以用来将任意的可打印字符修改为任意其它的可打印字符。如果您想将不可打印字符修改为可打印字符—例如,铃铛修改为单词 “bell”—sed 不是适于完成这项工作的工具(但 tr 是)。

有时,您不想修改在一个文件中出现的所有指定项目。有时,您只想在满足某些条件时才作修改—例如,在与其它一些数据匹配之后才作修改。为了说明这一点,请考虑以下文本文件:

$ cat sample_one

one 1

two 1

three 1

one 1

two 1

two 1

three 1

$

假定希望用 “2” 来替换 “1”,但仅在单词 “two” 之后才作替换,而不是每一行的所有位置。通过指定在给出替换命令之前必须存在一次匹配,可以实现这一点:

$ sed ‘/two/ s/1/2/’ sample_one

one 1

two 2

three 1

one 1

two 2

two 2

three 1

$

现在,使其更加准确:

$ sed ‘

> /two/ s/1/2/

> /three/ s/1/3/’ sample_one

one 1

two 2

three 3

one 1

two 2

two 2

three 3

$

请再次记住唯一改变了的是显示。如果您查看源文件,您将发现它始终保持不变。您必须将输出保存至另一个文件,以实现永久保存。值得重复的是,不 对源文件作修改实际是祸中有福—它让您能够对文件进行试验而不会造成任何实际的损害,直到让正确命令以您预期和希望的方式进行工作。

以下命令将修改后的输出保存至一个新的文件:

$ sed ‘

> /two/ s/1/2/

> /three/ s/1/3/’ sample_one > sample_two

该输出文件将所有修改合并在其中,并且这些修改通常将在屏幕上显示。现在可以用 head、cat 或任意其它类似的实用工具来进行查看。

脚本文件

sed 工具允许您创建一个脚本文件,其中包含从该文件而不是在命令行进行处理的命令,并且 sed 工具通过 “-f” 选项来引用。通过创建一个脚本文件,您能够一次又一次地重复运行相同的操作,并指定比每次希望从命令行进行处理的操作详细得多的操作。

考虑以下脚本文件:

$ cat sedlist

/two/ s/1/2/

/three/ s/1/3/

$

现在可以在数据文件上使用脚本文件,获得和我们之前看到的相同的结果:

$ sed -f sedlist sample_one

one 1

two 2

three 3

one 1

two 2

two 2

three 3

$

注意当调用 “-f” 选项时,在源文件内或命令行中不使用撇号。脚本文件,也称为源文件,对于想重复多次的操作和从命令行运行可能出错的复杂命令很有价值。编辑源文件并修改一个字符比在命令行中重新输入一条多行的项目要容易得多。

  限制行

编辑器默认查看输入到流编辑器中的每一行,且默认在输入到流编辑器中的每一行上进行编辑。这可以通过在发出命令之前指定约束条件来进行修改。例如,只在此示例文件的输出的第 5 和第 6 行中用 “2” 来替换 “1”,命令将为:

$ sed ‘5,6 s/1/2/’ sample_one

one 1

two 1

three 1

one 1

two 2

two 2

three 1

$

在这种情况下,因为要修改的行是专门指定的,所以不需要替换命令。因此,您可以灵活地根据匹配准则(可以是行号或一种匹配模式)来选择要修改哪些行(从根本上限制修改)。

禁止显示

sed 默认将来自源文件的每一行显示到屏幕上(或重定向到一个文件中),而无论该行是否受到编辑操作的影响,”-n” 参数覆盖了这一操作。”-n” 覆盖了所有的显示,并且不显示任何一行,而无论它们是否被编辑操作修改。例如:

$ sed -n -f sedlist sample_one

$

$ sed -n -f sedlist sample_one > sample_two

$ cat sample_two

$

在第一个示例中,屏幕上不显示任何东西。在第二个示例中,不修改任何东西,因此不将任何东西写到新的文件中—它最后是空的。这不是否定了编辑的 全部目的吗?为什么这是有用的?它是有用的仅因为 “-n” 选项能够被一条显示命令 (-p) 覆盖。为了说明这一点,假定现在像下面这样对脚本文件进行了修改:

$ cat sedlist

/two/ s/1/2/p

/three/ s/1/3/p

$

然后下面是运行它的结果:

$ sed -n -f sedlist sample_one

two 2

three 3

two 2

two 2

three 3

$

保持不变的行全部不被显示。只有受到编辑操作影响的行被显示了。在这种方式下,可以仅取出这些行,进行修改,然后把它们放到一个单独的文件中:

$ sed -n -f sedlist sample_one > sample_two

$

$ cat sample_two

two 2

three 3

two 2

two 2

three 3

$

利用它的另一种方法是只显示一定数量的行。例如,只显示 2-6 行,同时不做其它的编辑修改:

$ sed -n ‘2,6p’ sample_one

two 1

three 1

one 1

two 1

two 1

$

其它所有的行被忽略,只有 2-6 行作为输出显示。这是一项出色的功能,其它任何工具都不能容易地实现。Head 将显示一个文件的顶部,而 tail 将显示一个文件的底部,但 sed 允许从任意位置取出想要的任意内容。

删除行

用一个值替换另一个值远非流编辑器可以执行的唯一功能。它还具有许多的潜在功能,在我看来第二种最常用的功能是删除。删除与替换的工作方式相同,只是它删除指定的行(如果您想要删除一个单词而不是一行,不要考虑删除,而应考虑用空的内容来替换它—s/cat//)。

该命令的语法是:

‘{what to find} d’

从 sample_one 文件中删除包含 “two” 的所有行:

$ sed ‘/two/ d’ sample_one

one 1

three 1

one 1

three 1

$

*****************************************************************************

本文由正泰linux http://linux-down.kmip.net 搜集,整理,如需转载,请注明出处!

本站有大量的linux电子教程,软件,技术文档,欢迎大家访问!站长阿泰qq:253222170

******************************************************************************

从显示屏中删除前三行,而不管它们的内容是什么:

$ sed ‘1,3 d’ sample_one

one 1

two 1

two 1

three 1

$

只显示剩下的行,前三行不在显示屏中出现。对于流编辑器,一般当它们涉及到全局表达式时,特别是应用于删除操作时,有几点要记住:

  上三角号 (^) 表示一行的开始,因此,如果 “two” 是该行的头三个字符,则

sed ‘/^two/ d’ sample_one

将只删除该行。

美元符号 ($) 代表文件的结尾,或一行的结尾,因此,如果 “two” 是该行的最后三个字符,则

sed ‘/two$/ d’ sample_one

将只删除该行。

将这两者结合在一起的结果:

sed ‘/^$/ d’ {filename}

删除文件中的所有空白行。例如,以下命令将 “1” 替换为 “2”,以及将 “1” 替换为 “3”,并删除文件中所有尾随的空行:

$ sed ‘/two/ s/1/2/; /three/ s/1/3/; /^$/ d’ sample_one

one 1

two 1

three 1

one 1

two 2

two 2

three 1

$

其通常的用途是删除一个标题。以下命令将删除文件中所有的行,从第一行直到第一个空行:

sed ‘1,/^$/ d’ {filename}

添加和插入文本

可以结合使用 sed 和 “a” 选项将文本添加到一个文件的末尾。实现方法如下:

$ sed ‘$a\\

> This is where we stop\\

> the test’ sample_one

one 1

two 1

three 1

one 1

two 1

two 1

three 1

This is where we stop

the test

$

在该命令中,美元符号 ($) 表示文本将被添加到文件的末尾。反斜线 (\\) 是必需的,它表示将插入一个回车符。如果它们被遗漏了,则将导致一个错误,显示该命令是错乱的;在任何要输入回车的地方您必须使用反斜线。

要将这些行添加到第 4 和第 5 个位置而不是末尾,则命令变为:

$ sed ‘3a\\

> This is where we stop\\

> the test’ sample_one

one 1

two 1

three 1

This is where we stop

the test

one 1

two 1

two 1

three 1

$

这将文本添加到第 3 行之后。和几乎所有的编辑器一样,您可以选择插入而不是添加(如果您希望这样的话)。这两者的区别是添加跟在指定的行之后,而插入从指定的行开始。当用插入来代替添加时,只需用 “i” 来代替 “a”,如下所示:

$ sed ‘3i\\

> This is where we stop\\

> the test’ sample_one

one 1

two 1

This is where we stop

the test

three 1

one 1

two 1

two 1

three 1

$

新的文本出现在输出的中间位置,而处理通常在指定的操作执行以后继续进行。

读写文件

重定向输出的功能已经演示过了,但需要指出的是,在编辑命令运行期间可以同步地读入和写出文件。例如,执行替换,并将 1-3 行写到名称为 sample_three 的文件中:

$ sed ‘

> /two/ s/1/2/

> /three/ s/1/3/

> 1,3 w sample_three’ sample_one

one 1

two 2

three 3

one 1

two 2

two 2

three 3

$

$ cat sample_three

one 1

two 2

three 3

$

由于为 w (write) 命令指定了 “1,3”,所以只有指定的行被写到了新文件中。无论被写的是哪些行,所有的行都在默认输出中显示。

修改命令

除了替换项目之外,还可以将行从一个值修改为另一个值。要记住的是,替换是对字符逐个进行,而修改功能与删除类似,它影响整行:

$ sed ‘/two/ c\\

> We are no longer using two’ sample_one

one 1

We are no longer using two

three 1

one 1

We are no longer using two

We are no longer using two

three 1

$

修改命令与替换的工作方式很相似,但在范围上要更大些—将一个项目完全替换为另一个项目,而无论字符内容或上下文。夸张一点讲,当使用替换时, 只有字符 “1” 被字符 “2” 替换,而当使用修改时,原来的整行将被修改。在两种情况下,要寻找的匹配条件都仅为 “two”。

修改全部但……

对于大多数 sed 命令,详细说明各种功能要进行何种修改。利用感叹号,可以在除指定位置之外的任何地方执行修改—与默认的操作完全相反。

例如,要删除包含单词 “two” 的所有行,操作为:

$ sed ‘/two/ d’ sample_one

one 1

three 1

one 1

three 1

$

而要删除除包含单词 “two” 的行之外的所有行,则语法变为:

$ sed ‘/two/ !d’ sample_one

two 1

two 1

two 1

$

如果您有一个文件包含一系列项目,并且想对文件中的每个项目执行一个操作,那么首先对那些项目进行一次智能扫描并考虑将要做什么是很重要的。为了使事情变得更简单,您可以将 sed 与任意迭代例程(for、while、until)结合来实现这一目的。

比如说,假定您有一个名为 “animals” 的文件,其中包含以下项目:

pig

horse

elephant

cow

dog

cat

您希望运行以下例程:

#mcd.ksh

for I in $*

do

echo Old McDonald had a $I

echo E-I, E-I-O

done

结果将为,每一行都显示在 “Old McDonald has a” 的末尾。虽然对于这些项目的大部分这是正确的,但对于 “elephant” 项目,它有语法错误,因为结果应当为 “an elephant” 而不是 “a elephant”。利用 sed,您可以在来自 shell 文件的输出中检查这种语法错误,并通过首先创建一个命令文件来即时地更正它们:

#sublist

/ a a/ s/ a / an /

/ a e/ s/ a / an /

/a i/ s / a / an /

/a o/ s/ a / an /

/a u/ s/ a / an /

然后执行以下过程:

$ sh mcd.ksh ‘cat animals’ | sed -f sublist

现在,在运行了 mcd 脚本之后,sed 将在输出中搜索单个字母 a (空格,”a”,空格)之后紧跟了一个元音的任意位置。如果这种位置存在,它将把该序列修改为空格,”an”,空格。这样就使问题更正后才显示在屏幕上, 并确保各处的编辑人员在晚上可以更容易地入睡。结果是:

Old McDonald had a pig

E-I, E-I-O

Old McDonald had a horse

E-I, E-I-O

Old McDonald had an elephant

E-I, E-I-O

Old McDonald had a cow

E-I, E-I-O

Old McDonald had a dog

E-I, E-I-O

Old McDonald had a cat

E-I, E-I-O

提前退出

sed 默认读取整个文件,并只在到达末尾时才停止。不过,您可以使用退出命令提前停止处理。只能指定一条退出命令,而处理将一直持续直到满足调用退出命令的条件。

例如,仅在文件的前五行上执行替换,然后退出:

$ sed ‘

> /two/ s/1/2/

> /three/ s/1/3/

> 5q’ sample_one

one 1

two 2

three 3

one 1

two 2

$

在退出命令之前的项目可以是一个行号(如上所示),或者一条查找/匹配命令:

$ sed ‘

> /two/ s/1/2/

> /three/ s/1/3/

> /three/q’ sample_one

one 1

two 2

three 3

$

您还可以使用退出命令来查看超过一定标准数目的行,并增加比 head 中的功能更强的功能。例如,head 命令允许您指定您想要查看一个文件的前多少行—默认数为 10,但可以使用从 1 到 99 的任意一个数字。如果您想查看一个文件的前 110 行,您用 head 不能实现这一目的,但用 sed 可以:

sed 110q filename
  处理问题

当使用 sed 时,要记住的重要事项是它的工作方式。它的工作方式是:读入一行,在该行上执行它已知要执行的所有任务,然后继续处理下一行。每一行都受给定的每一个编辑命令的影响。

如果您的操作顺序没有十分彻底地考虑清楚,那么这可能会很麻烦。例如,假定您需要将所有的 “two” 项目修改为 “three”,然后将所有的 “three” 修改为 “four”:

$ sed ‘

> /two/ s/two/three/

> /three/ s/three/four/’ sample_one

one 1

four 1

four 1

one 1

four 1

four 1

four 1

$

最初读取的 “two” 被修改为 “three”。然后它满足为下一次编辑建立的准则,从而变为 “four”。最终的结果不是想要的结果—现在除了 “four” 没有别的项目了,而本来应该有 “three” 和 “four”。

当执行这种操作时,您必须非常用心地注意指定操作的方式,并按某种顺序来安排它们,使得操作之间不会互相影响。例如:

$ sed ‘

> /three/ s/three/four/

> /two/ s/two/three/’ sample_one

one 1

three 1

four 1

one 1

three 1

three 1

four 1

$

这非常有效,因为 “three” 值在 “two” 变成 “three” 之前得到修改。

标签和注释

可以在 sed 脚本文件中放置标签,这样一旦文件变得庞大,可以更容易地说明正在发生的事情。存在各种各样与这些标签相关的命令,它们包括:

接下来的步骤

访问并收藏 Linux 技术中心

阅读 Dale Dougherty 和 Arnold Robbins 的著作 sed & awk, 2nd Edition (O’Reilly & Associates 出版社)。

: 冒号表示一个标签名称。例如:

:HERE

以冒号开始的标签可以由 “b” 和 “t” 命令处理。

b {label} 充当 “goto” 语句的作用,将处理发送至前面有一个冒号的标签。例如,

b HERE

将处理发送给行

:HERE

如果紧跟 b 之后没有指定任何标签,则处理转至脚本文件的末尾。

t {label} 只要自上次输入行或执行一次 “t” 命令以来进行了替换操作,就转至该标签。和 “b” 一样,如果没有给定标签名,则处理转至脚本文件的末尾。

# 符号作为一行的第一个字符将使整行被当作注释处理。注释行与标签不同,不能使用 b 或 t 命令来转到注释行上。

进一步的研究

sed 实用工具是 Linux 管理员拥有的最强大和灵活的工具之一。虽然本文覆盖了许多基础知识,但对于这一具有丰富功能的工具仅是蜻蜓点水。关于更多信息,最好的来源之一是 Dale Dougherty 和 Arnold Robbins 的著作 sed & awk,现在从 O’Reilly & Associates 出版社推出了其第二版(参加“接下来的步骤”)。该出版社还推出了一本可以随身携带的袖珍参考。

from http://www.linuxidc.com/Linux/2007-09/7688.htm

archlinux安装桌面环境,startx:command not found/cannot execute “/usr/bin/sdm”

试用archlinux,根据http://www.ha97.com/3496.html(ArchLinux 2010.05安装及基本配置)操作。

但运行startx却得到command not found,在centos 6 上查startx,该文件位于/usr/bin/startx,属于xorg-x11-xinit包

[feng@fsc ~]$ whereis /usr/bin/startx
startx: /usr/bin/startx /usr/share/man/man1/startx.1.gz
[feng@fsc ~]$ rpm -qf /usr/bin/startx
xorg-x11-xinit-1.0.9-13.el6.i686

不幸的是pacman -S 却说没有这个包,经搜索得知在archlinux里,这个包包为xorg-xinit,感到不可理解的是,为什么这个包没有在安装xorg包时没在依赖检查里自动安装。

运行init 5进入gnome图形桌面时,出现INIT: cannot execute “/usr/bin/xdm”,要修改

/etc/inittab

x:5:respawn:/usr/bin/xdm -nodaemon

一行修改为,

x:5:respawn:/usr/sbin/gdm -nodaemon

目前的archlinux 包里没有了xdm,而以gdm代替,但inittab文件里却没有相应的更新。

看来archlinux真的不是那么容易,没有一定的linux经验难度。

本文是很久以前操作手记文章,那时折腾archlinux桌面,文章里写的这一步好像是通过了,但后来还是没有成功,忘了卡在哪里,就放弃了,以后再没有搞archlinux,本文也就无限期搁置了。于是本文在草稿箱里放了5年多。最近整理博客看其更新时间为 2011年10月3日 @ 15:32,这么久都没有继续,大概以后也不会续写了,直接发出来算了(2016-10-10 18:06)