之前为了方便连接到公网服务器,在本地SSH 客户端设置了socket代理。这样能加速访问服务器。
但是有一天,要访问局域网时,因为默认开了代理的缘故,本机SSH 无法连接到 局域网内的centos服务器。【其实是开了centos虚拟机,网络配置是桥接】
只要将本地的SSH取消socket代理就行了,这样就能访问局域网内的服务器了。
当你年老时,你是否常常想,要是年轻时多努力下该好。
之前为了方便连接到公网服务器,在本地SSH 客户端设置了socket代理。这样能加速访问服务器。
但是有一天,要访问局域网时,因为默认开了代理的缘故,本机SSH 无法连接到 局域网内的centos服务器。【其实是开了centos虚拟机,网络配置是桥接】
只要将本地的SSH取消socket代理就行了,这样就能访问局域网内的服务器了。
VNC (Virtual Network Console)是虚拟网络控制台的缩写。它 是一款优秀的远程控制工具软件,由著名的 AT&T 的欧洲研究实验室开发的。VNC 是在基于 UNIX 和 Linux 操作系统的免费的开源软件,远程控制能力强大,高效实用,其性能可以和 Windows 和 MAC 中的任何远程控制软件媲美。 在 Linux 中,VNC 包括以下四个命令:vncserver,vncviewer,vncpasswd,和 vncconnect。大多数情况下用户只需要其中的两个命令:vncserver 和 vncviewer。
VNC基本上是由两部分组成:一部分是客户端的应用程序(vncviewer);另外一部分是服务器端的应用程序(vncserver)。VNC的基本运行原理和一些Windows下的远程控制软件很相像。VNC的服务器端应用程序在UNIX和Linux操作系统中适应性很强,图形用户界面十分友好,看上去和Windows下的软件界面也很类似。在任何安装了客户端的应用程序(vncviewer)的Linux平台的计算机都能十分方便地和安装了服务器端的应用程序(vncserver)的计算机相互连接。另外,服务器端 (vncserver)还内建了Java Web接口,这样用户通过服务器端对其他计算机的操作就能通过Netscape显示出来了,这样的操作过程和显示方式比较直观方便。
楼主下载的是:VNC Viewer
https://www.realvnc.com/en/connect/download/viewer/
下载完,直接安装就行了。
# 1、下载linux桌面环境 yum groupinstall "GNOME Desktop" # 2、安装tigervnc 服务端软件 yum install tigervnc-server # 3、拷贝 vnc 配置文件 # In CentOS 7.0 there is change in the vncserver configuration file. # Before ContOS 7.0 it was /etc/sysconfig/vncservers and now # it have changed in /lib/systemd/system/[email protected]. # Next I will use the original file and create the configuration file as shown: cp /lib/systemd/system/[email protected] /etc/systemd/system/vncserver@:1.service
重点步骤:
# 4、编辑vnc配置文件 # Replace the string <USER> with appropriate vncuser’s username. # In my case I will be using the user root: vi /etc/systemd/system/vncserver@:1.service
旧版 vnc 配置文件:
# ... 前面一大堆文字 [Service] Type=forking # Clean any existing files in /tmp/.X11-unix environment ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :' #ExecStart=/sbin/runuser -l -c "/usr/bin/vncserver %i" #PIDFile=/home//.vnc/%H%i.pid ExecStart=/sbin/runuser -l srijan -c "/usr/bin/vncserver %i" PIDFile=/home/srijan/.vnc/%H%i.pid ExecStop=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :'
新版 VNC 配置文件:
# The vncserver service unit file # # Quick HowTo: # 1. Copy this file to /etc/systemd/system/[email protected] # 2. Replace with the actual user name and edit vncserver # parameters appropriately # ("User=" and "/home//.vnc/%H%i.pid") # 3. Run `systemctl daemon-reload` # 4. Run `systemctl enable vncserver@:.service` # # DO NOT RUN THIS SERVICE if your local area network is # untrusted! For a secure way of using VNC, you should # limit connections to the local host and then tunnel from # the machine you want to view VNC on (host A) to the machine # whose VNC output you want to view (host B) # # [user@hostA ~]$ ssh -v -C -L 590N:localhost:590M hostB # # this will open a connection on port 590N of your hostA to hostB's port 590M # (in fact, it ssh-connects to hostB and then connects to localhost (on hostB). # See the ssh man page for details on port forwarding) # # You can then point a VNC client on hostA at vncdisplay N of localhost and with # the help of ssh, you end up seeing what hostB makes available on port 590M # # Use "-nolisten tcp" to prevent X connections to your VNC server via TCP. # # Use "-localhost" to prevent remote VNC clients connecting except when # doing so through a secure tunnel. See the "-via" option in the # `man vncviewer' manual page. [Unit] Description=Remote desktop service (VNC) After=syslog.target network.target [Service] Type=forking User= # Clean any existing files in /tmp/.X11-unix environment ExecStartPre=-/usr/bin/vncserver -kill %i ExecStart=/usr/bin/vncserver %i PIDFile=/home//.vnc/%H%i.pid ExecStop=-/usr/bin/vncserver -kill %i [Install] WantedBy=multi-user.target
新版vnc配置文件,有一个坑
User= #改成 User=root PIDFile=/home//.vnc/%H%i.pid # 改成 PIDFile=/root/.vnc/%H%i.pid # 普通用户的话,目录都是 /home/用户名 # root 用户的目录是 /root # 注意啊 这个是坑爹 的地方
5、配置防火墙
firewall-cmd --permanent --zone=public --add-service vnc-server firewall-cmd --reload
6、启动 vncserver ;就是开启 VNC 服务器,开启的同时,先让你设置个密码(这个密码是客户端需要输入的记住)
[root@server1 ~]# vncserver You will require a password to access your desktops. Password:<--yourvncpassword Verify:<--yourvncpassword xauth: file /home/srijan/.Xauthority does not exist New 'server1.example.com:1 (srijan)' desktop is server1.example.com:1 Creating default startup script /home/kishore/.vnc/xstartup Starting applications specified in /home/kishore/.vnc/xstartup Log file is /home/srijan/.vnc/server1.example.com:1.log [root@server1 ~]#
其实这个时候,vnc服务器 已经可以运行了。
这里的配置的数字1,其实就是 从 VNC 端口 5900开始的,数字1 代表 5901端口,可接收远程连接请求。
7、设置开机自启动
Now make the service enabled on after every reboot with root credentials:
systemctl daemon-reload systemctl enable vncserver@:1.service reboot systemctl start vncserver@:1.service
[root@localhost system]# systemctl start vncserver@:1.service Job for vncserver@:1.service failed. See ‘systemctl status vncserver@:1.service’ and ‘journ alctl -xn’ for details.[root@localhost system]# systemctl status vncserver@:1.service vncserver@:1.service - Remote desktop service (VNC) Loaded: loaded (/etc/systemd/system/vncserver@:1.service; enabled) Active: failed (Result: exit-code) since Thu 2015-04-23 16:04:58 CST; 14s ago Process: 24764 ExecStart=/sbin/runuser -l root -c /usr/bin/vncserver :1 -geometry 1280x10 24 -depth 24 (code=exited, status=98) Process: 24760 ExecStartPre=/bin/sh -c /usr/bin/vncserver -kill %1 > /dev/null 2>&1 || : (code=exited, status=0/SUCCESS) Apr 23 16:04:58 localhost.localdomain systemd[1]: vncserver@:1.service: control proces…98 Apr 23 16:04:58 localhost.localdomain systemd[1]: Failed to start Remote desktop servi…). Apr 23 16:04:58 localhost.localdomain systemd[1]: Unit vncserver@:1.service entered fa…e. Hint: Some lines were ellipsized, use -l to show in full. [root@localhost system]#
解决方法:
1、可能是 临时文件 问题。
rm -rf /tmp/.X11-unix
2、可能是端口被占用问题,或者死锁了。
[root@testdb ~]# lsof -i:5901 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME Xvnc 17513 root 9u IPv4 365529 0t0 TCP localhost:5901 (LISTEN) Xvnc 17513 root 10u IPv6 365530 0t0 TCP localhost:5901 (LISTEN) [root@testdb ~]# kill 17513 [root@testdb ~]#
重新启动系统,就可以啦。
[root@testdb ~]# vncserver -h usage: vncserver [:<number>] [-name <desktop-name>] [-depth <depth>] [-geometry <width>x<height>] [-pixelformat rgbNNN|bgrNNN] [-fp <font-path>] [-cc <visual>] [-fg] [-autokill] [-noxstartup] [-xstartup <file>] <Xvnc-options>... vncserver -kill <X-display> vncserver -list [root@testdb ~]#
# 启动 vnc 服务端 5901端口(分配一个窗口) 命令 vncserver :1 # 关闭 vnc 服务端 5901 端口(一个窗口) 命令 vncserver -kill :1 # 查看 当前 有 多少个 vnc 窗口 命令 vncserver -list ########## 下面就是命令行 能看到的结果 # TigerVNC server sessions: # # X DISPLAY # PROCESS ID # :1 18936 ##################################
利用ssh 登入centos7系统,或者用vnc登录也行。
[root@testdb ~]# ls -a . Downloads Pictures .. .esd_auth .pki anaconda-ks.cfg Firefox_wallpaper.png Public .bash_history get-pip.py .ssh .bash_logout .gvfs .tcshrc .bash_profile html.tar.gz Templates .bashrc .ICEauthority Videos .cache .local .viminfo .config .mozilla .vnc .cshrc Music .Xauthority Desktop mysql57-community-release-el7-8.noarch.rpm Documents .mysql_history [root@li1582-175 ~]# cd .vnc [root@li1582-175 .vnc]# ls -a . li1582-175.members.linode.com:1.log passwd .. li1582-175.members.linode.com:2.log xstartup config localhost.localdomain:1.log [root@testdb .vnc]# vim config
vim编辑完文件后,保存并重启VNC服务端。
#关闭vnc服务器, vncserver -kill :1 #重启vnc服务器 vncserver :1
客户端操作如下:
1、SSH本地端口转发。VNC远程连接过程中需要保持一直在后台运行。
假定服务器ip 是 128.128.128.128
假定服务器SSH 端口是 8888
ssh -v -C -L 5901:localhost:5901 [email protected] -p 8888
2、登录vnc客户端:
只需将vnc服务器填本机即可。
VNC SERVER:127.0.0.1:1
部分内容参考自:https://www.howtoforge.com/vnc-server-installation-on-centos-7
你是不是经常需要 SSH 或者 telent 远程登录到 Linux 服务器?你是不是经常为一些长时间运行的任务而头疼,比如系统备份、ftp 传输等等。通常情况下我们都是为每一个这样的任务开一个远程终端窗口,因为他们执行的时间太长了。必须等待它执行完毕,在此期间可不能关掉窗口或者断开连接,否则这个任务就会被杀掉,一切半途而废了。
screen : 退出销毁操作
screen -ls There is a screen on: 30339.pyapi (Detached) 1 Socket in /var/run/screen/S-root. screen -r 30339 //进入要中断的screen exit //exit 或者 control +c 退出 screen
让我们来看看为什么关掉窗口/断开连接会使得正在运行的程序死掉。
在Linux/Unix中,有这样几个概念:
根据POSIX.1定义:
因此当网络断开或终端窗口关闭后,控制进程收到SIGHUP信号退出,会导致该会话期内其他进程退出。
我们来看一个例子。打开两个SSH终端窗口,在其中一个运行top命令。
[root@tivf09 root]# top
在另一个终端窗口,找到top的进程ID为5180,其父进程ID为5128,即登录shell。
[root@tivf09 root]# ps -ef|grep top root 5180 5128 0 01:03 pts/0 00:00:02 top root 5857 3672 0 01:12 pts/2 00:00:00 grep top
使用pstree命令可以更清楚地看到这个关系:
[root@tivf09 root]# pstree -H 5180|grep top |-sshd-+-sshd---bash---top
使用ps-xj命令可以看到,登录shell(PID 5128)和top在同一个会话期,shell为会话期首进程,所在进程组PGID为5128,top所在进程组PGID为5180,为前台进程组。
[root@tivf09 root]# ps -xj|grep 5128 5126 5128 5128 5128 pts/0 5180 S 0 0:00 -bash 5128 5180 5180 5128 pts/0 5180 S 0 0:50 top 3672 18095 18094 3672 pts/2 18094 S 0 0:00 grep 5128
关闭第一个SSH窗口,在另一个窗口中可以看到top也被杀掉了。
[root@tivf09 root]# ps -ef|grep 5128 root 18699 3672 0 04:35 pts/2 00:00:00 grep 5128
如果我们可以忽略SIGHUP信号,关掉窗口应该就不会影响程序的运行了。nohup命令可以达到这个目的,如果程序的标准输出/标准错误是终端,nohup默认将其重定向到nohup.out文件。值得注意的是nohup命令只是使得程序忽略SIGHUP信号,还需要使用标记&把它放在后台运行。
nohup <command> [argument…] &
虽然nohup很容易使用,但还是比较“简陋”的,对于简单的命令能够应付过来,对于复杂的需要人机交互的任务就麻烦了。
其实我们可以使用一个更为强大的实用程序screen。流行的Linux发行版(例如Red Hat Enterprise Linux 4)通常会自带screen实用程序,如果没有的话,可以从GNU screen的官方网站下载。
[root@tivf06 ~]# rpm -qa|grep screen xscreensaver-4.18-5.rhel4.11 screen-4.0.2-5
# 先在 服务器端 安装 screen [root@ttsdy ~]# yum install screen
简单来说,Screen是一个可以在多个进程之间多路复用一个物理终端的窗口管理器。Screen中有会话的概念,用户可以在一个screen会话中创建多个screen窗口,在每一个screen窗口中就像操作一个真实的telnet/SSH连接窗口那样。在screen中创建一个新的窗口有这样几种方式:
1.直接在命令行键入screen命令
[bash] [root@tivf06 ~]# screen [/bash] Screen将创建一个执行shell的全屏窗口。你可以执行任意shell程序,就像在ssh窗口中那样。在该窗口中键入exit退出该窗口,如果这是该screen会话的唯一窗口,该screen会话退出,否则screen自动切换到前一个窗口。 2.Screen命令后跟你要执行的程序。[root@tivf06 ~]# screen vi test.cScreen创建一个执行vi test.c的单窗口会话,退出vi将退出该窗口/会话。
3.以上两种方式都创建新的screen会话。我们还可以在一个已有screen会话中创建新的窗口。在当前screen窗口中键入
C-a c
,即Ctrl键+a键,之后再按下c键,screen 在该会话内生成一个新的窗口并切换到该窗口。screen还有更高级的功能。你可以不中断screen窗口中程序的运行而暂时断开(detach)screen会话,并在随后时间重新连接(attach)该会话,重新控制各窗口中运行的程序。例如,我们打开一个screen窗口编辑/tmp/abc文件:
[root@tivf06 ~]# screen vi /tmp/abc之后我们想暂时退出做点别的事情,比如出去散散步,那么在screen窗口键入
C-a d
,Screen会给出detached提示:暂时中断会话
半个小时之后回来了,找到该screen会话:
[root@tivf06 ~]# screen -ls There is a screen on: 16582.pts-1.tivf06 (Detached) 1 Socket in /tmp/screens/S-root.重新连接会话:
[root@tivf06 ~]# screen -r 16582看看出现什么了,太棒了,一切都在。继续干吧。
你可能注意到给screen发送命令使用了特殊的键组合C-a。这是因为我们在键盘上键入的信息是直接发送给当前screen窗口,必须用其他方式向screen窗口管理器发出命令,默认情况下,screen接收以C-a开始的命令。这种命令形式在screen中叫做键绑定(key binding),C-a叫做命令字符(command character)。
可以通过
C-a ?
来查看所有的键绑定,常用的键绑定有:Screen常用选项
使用键绑定C-a ?命令可以看到, 默认的命令字符(Command key)为C-a,转义C-a(literal ^a)的字符为a:
Screen 常用选项
因为screen把C-a看作是screen命令的开始,所以如果你想要screen窗口接收到C-a字符,就要输入C-a a。Screen也允许你使用-e选项设置自己的命令字符和转义字符,其格式为:
-exy x为命令字符,y为转义命令字符的字符
下面命令启动的screen会话指定了命令字符为C-t,转义C-t的字符为t,通过C-t ?命令可以看到该变化。
[root@tivf18 root]# screen -e^tt自定义命令字符和转义字符
其他常用的命令选项有:
下例显示当前有两个处于detached状态的screen会话,你可以使用screen -r <screen_pid>重新连接上:
[root@tivf18 root]# screen –ls There are screens on: 8736.pts-1.tivf18 (Detached) 8462.pts-0.tivf18 (Detached) 2 Sockets in /root/.screen. [root@tivf18 root]# screen –r 8736如果由于某种原因其中一个会话死掉了(例如人为杀掉该会话),这时screen -list会显示该会话为dead状态。使用screen -wipe命令清除该会话:
[root@tivf18 root]# kill -9 8462 [root@tivf18 root]# screen -ls There are screens on: 8736.pts-1.tivf18 (Detached) 8462.pts-0.tivf18 (Dead ???) Remove dead screens with 'screen -wipe'. 2 Sockets in /root/.screen. [root@tivf18 root]# screen -wipe There are screens on: 8736.pts-1.tivf18 (Detached) 8462.pts-0.tivf18 (Removed) 1 socket wiped out. 1 Socket in /root/.screen. [root@tivf18 root]# screen -ls There is a screen on: 8736.pts-1.tivf18 (Detached) 1 Socket in /root/.screen. [root@tivf18 root]#-d –m 选项是一对很有意思的搭档。他们启动一个开始就处于断开模式的会话。你可以在随后需要的时候连接上该会话。有时候这是一个很有用的功能,比如我们可以使用它调试后台程序。该选项一个更常用的搭配是:-dmS sessionname
启动一个初始状态断开的screen会话:
[root@tivf06 tianq]# screen -dmS mygdb gdb execlp_test连接该会话:
[root@tivf06 tianq]# screen -r mygdb管理你的远程会话
先来看看如何使用screen解决SIGHUP问题,比如现在我们要ftp传输一个大文件。如果按老的办法,SSH登录到系统,直接ftp命令开始传输,之后。。如果网络速度还可以,恭喜你,不用等太长时间了;如果网络不好,老老实实等着吧,只能传输完毕再断开SSH连接了。让我们使用screen来试试。
SSH登录到系统,在命令行键入screen。
[root@tivf18 root]# screen在screen shell窗口中输入ftp命令,登录,开始传输。不愿意等了?OK,在窗口中键入C-a d:
管理你的远程会话
然后。。退出SSH登录?随你怎样,只要别杀掉screen会话。
是不是很方便?更进一步,其实我们可以利用screen这种功能来管理你的远程会话,保存你所有的工作内容。你是不是每次登录到系统都要开很多窗口,然后每天都要重复打开关闭这些窗口?让screen来帮你“保存”吧,你只需要打开一个ssh窗口,创建需要的screen窗口,退出的时候C-a d“保存”你的工作,下次登录后直接screen -r <screen_pid>就可以了。
最好能给每个窗口起一个名字,这样好记些。使用C-a A给窗口起名字。使用C-a w可以看到这些窗口名字,可能名字出现的位置不同。使用putty:
putty
使用telnet:
telnet
更多Screen功能
Screen提供了丰富强大的定制功能。你可以在Screen的默认两级配置文件/etc/screenrc和$HOME/.screenrc中指定更多,例如设定screen选项,定制绑定键,设定screen会话自启动窗口,启用多用户模式,定制用户访问权限控制等等。如果你愿意的话,也可以自己指定screen配置文件。
以多用户功能为例,screen默认是以单用户模式运行的,你需要在配置文件中指定multiuser on 来打开多用户模式,通过acl*(acladd,acldel,aclchg...)命令,你可以灵活配置其他用户访问你的screen会话。更多配置文件内容请参考screen的man页。
参考资料
转载自:https://www.ibm.com/developerworks/cn/linux/l-cn-screen/
图片来自: http://www.cnblogs.com/zhangsf/archive/2013/06/13/3134409.html
公司新员工学习有用到,Vim官网的手册又太大而全,而网上各方资料要么不全面,要么不够基础。在网上搜集各方资料,按照自己的框架整理一份Vim入门基础教程,分享出来。特点是偏向基础,但对入门者来说足够全面,而且结构框架清晰。
另外,参考资料众多,没有一一标出来,如果作者看到,请联系我确认一下是否参考了你的资料,我会在文中标注出来。
Vim(Vi[Improved])编辑器是功能强大的跨平台文本文件编辑工具,继承自Unix系统的Vi编辑器,支持Linux/Mac OS X/Windows系统,利用它可以建立、修改文本文件。进入Vim编辑程序,可以在终端输入下面的命令:
$vim [filename]
其中filename
是要编辑器的文件的路径名。如果文件不存在,它将为你建立一个新文件。Vim编辑程序有三种操作模式,分别称为 编辑模式、插入模式 和 命令模式,当运行Vim时,首先进入编辑模式。
vim中显示行号命令 :set nu
Vim编辑方式的主要用途是在被编辑的文件中移动光标的位置。一旦光标移到到所要的位置,就可以进行剪切和粘贴正文块,删除正文和插入新的正文。当完成所有的编辑工作后,需要保存编辑器结果,退出编辑程序回到终端,可以发出ZZ
命令,连续按两次大写的Z
键。
如果键盘上有上、下、左、右箭头的导航键,就由这些键来完成光标的移动。另外,可以用下面的键完成同样的 按字符移动 功能:
k 上移; j 下移; h 左移; l 右移。
上面这4个键将光标位置每次移动一行或一个 字符 。Vim还提供稍大范围移动光标的命令:
ctrl+f 在文件中前移一页(相当于 page down); ctrl+b 在文件中后移一页(相当于 page up);
更大范围的移动:
* 当光标停留在一个单词上,* 键会在文件内搜索该单词,并跳转到下一处; # 当光标停留在一个单词上,# 在文件内搜索该单词,并跳转到上一处; (/) 移动到 前/后 句 的开始; {/} 跳转到 当前/下一个 段落 的开始。 g_ 到本行最后一个不是 blank 字符的位置。 fa 到下一个为 a 的字符处,你也可以fs到下一个为s的字符。 t, 到逗号前的第一个字符。逗号可以变成其它字符。 3fa 在当前行查找第三个出现的 a。 F/T 和 f 和 t 一样,只不过是相反方向; gg 将光标定位到文件第一行起始位置; G 将光标定位到文件最后一行起始位置; NG或Ngg 将光标定位到第 N 行的起始位置。
在屏幕中找到需要的 一页 时,可以用下面的命令快速移动光标:
H 将光标移到屏幕上的起始行(或最上行); M 将光标移到屏幕中间; L 将光标移到屏幕最后一行。
同样需要注意字母的大小写。H
和 L
命令还可以加数字。如 2H
表示将光标移到屏幕的第2行,3L
表示将光标移到屏幕的倒数第3行。
当将光标移到所要的行是,行内移动 光标可以用下面的命令来实现:
w 右移光标到下一个字的开头; e 右移光标到一个字的末尾; b 左移光标到前一个字的开头; 0 数字0,左移光标到本行的开始; $ 右移光标,到本行的末尾; ^ 移动光标,到本行的第一个非空字符。
和许多先进的编辑器一样,Vim 提供了强大的字符串搜索功能。要查找文件中指定字或短语出现的位置,可以用Vim直接进行搜索,而不必以手工方式进行。搜索方法是:键入字符 /
,后面跟以要搜索的字符串,然后按回车键。编辑程序执行正向搜索(即朝文件末尾方向),并在找到指定字符串后,将光标停到该字符串的开头;键入 n
命令可以继续执行搜索,找出这一字符串下次出现的位置。用字符 ?
取代 /
,可以实现反向搜索(朝文件开头方向)。例如:
/str1 正向搜索字符串 str1; n 继续搜索,找出 str1 字符串下次出现的位置; N 继续搜索,找出 str1 字符串上一次出现的位置; ?str2 反向搜索字符串 str2 。
无论搜索方向如何,当到达文件末尾或开头时,搜索工作会循环到文件的另一端并继续执行。
Vim中执行搜索匹配最强大的地方是结合 正则表达式 来搜索,后续将会介绍。
Vim常规的删除命令是 d
、 x
(前者删除 行
,后者删除 字符
),结合Vim的其他特性可以实现基础的删除功能。将光标定位于文件内指定位置后,可以用其他字符来替换光标所指向的字符,或从当前光标位置删除一个或多个字符或一行、多行。例如:
rc 用 c 替换光标所指向的当前字符; nrc 用 c 替换光标所指向的前 n 个字符; 5rA 用 A 替换光标所指向的前 5 个字符; x 删除光标所指向的当前字符; nx 删除光标所指向的前 n 个字符; 3x 删除光标所指向的前 3 个字符; dw 删除光标右侧的字; ndw 删除光标右侧的 n 个字; 3dw 删除光标右侧的 3 个字; db 删除光标左侧的字; ndb 删除光标左侧的 n 个字; 5db 删除光标左侧的 5 个字; dd 删除光标所在行,并去除空隙; ndd 删除(剪切) n 行内容,并去除空隙; 3dd 删除(剪切) 3 行内容,并去除空隙;
其他常用的删除命令有:
d$ 从当前光标起删除字符直到行的结束; d0 从当前光标起删除字符直到行的开始; J 删除本行的回车符(CR),并和下一行合并。
Vim常规的替换命令有 c
和 s
,结合Vim的其他特性可以实现基础的替换功能,不过替换命令执行以后,通常会由 编辑模式 进入 插入模式 :
s 用输入的正文替换光标所指向的字符; S 删除当前行,并进入插入模式; ns 用输入的正文替换光标右侧 n 个字符; nS 删除当前行在内的 n 行,并进入插入模式; cw 用输入的正文替换光标右侧的字; cW 用输入的正文替换从光标到行尾的所有字符(同 c$ ); ncw 用输入的正文替换光标右侧的 n 个字; cb 用输入的正文替换光标左侧的字; ncb 用输入的正文替换光标左侧的 n 个字; cd 用输入的正文替换光标的所在行; ncd 用输入的正文替换光标下面的 n 行; c$ 用输入的正文替换从光标开始到本行末尾的所有字符; c0 用输入的正文替换从本行开头到光标的所有字符。
从正文中删除的内容(如字符、字或行)并没有真正丢失,而是被剪切并复制到了一个内存缓冲区中。用户可将其粘贴到正文中的指定位置。完成这一操作的命令是:
p 小写字母 p,将缓冲区的内容粘贴到光标的后面; P 大写字母 P,将缓冲区的内容粘贴到光标的前面。
如果缓冲区的内容是字符或字,直接粘贴在光标的前面或后面;如果缓冲区的内容为整行正文,执行上述粘贴命令将会粘贴在当前光标所在行的上一行或下一行。
注意上述两个命令中字母的大小写。Vim 编辑器经常以一对大、小写字母(如 p
和 P
)来提供一对相似的功能。通常,小写命令在光标的后面进行操作,大写命令在光标的前面进行操作。
有时需要复制一段正文到新位置,同时保留原有位置的内容。这种情况下,首先应当把指定内容复制(而不是剪切)到内存缓冲区。完成这一操作的命令是:
yy 复制当前行到内存缓冲区; nyy 复制 n 行内容到内存缓冲区; 5yy 复制 5 行内容到内存缓冲区; “+y 复制 1 行到操作系统的粘贴板; “+nyy 复制 n 行到操作系统的粘贴板。
在编辑文档的过程中,为消除某个错误的编辑命令造成的后果,可以用撤消命令。另外,如果用户希望在新的光标位置重复前面执行过的编辑命令,可用重复命令。
u 撤消前一条命令的结果; . 重复最后一条修改正文的命令。
在编辑模式下正确定位光标之后,可用以下命令切换到插入模式:
i 在光标左侧插入正文 a 在光标右侧插入正文 o 在光标所在行的下一行增添新行 O 在光标所在行的上一行增添新行 I 在光标所在行的开头插入 A 在光标所在行的末尾插入
退出插入模式的方法是,按 ESC
键或组合键 Ctrl+[
,退出插入模式之后,将会进入编辑模式 。
在Vim的命令模式下,可以使用复杂的命令。在编辑模式下键入 :
,光标就跳到屏幕最后一行,并在那里显示冒号,此时已进入命令模式。命令模式又称 末行模式 ,用户输入的内容均显示在屏幕的最后一行,按回车键,Vim 执行命令。
在已经启动的Vim中打开一个文件需要用 :e
命令:
:e path_to_file/filename
保存当前编辑的文件需要用 :w
命令(单词 write
的缩写):
:w
将当前文件另存为 file_temp
则:
:w file_temp
在编辑模式下可以用 ZZ
命令退出Vim编辑程序,该命令保存对正文所作的修改,覆盖原始文件。如果只需要退出编辑程序,而不打算保存编辑的内容,可用下面的命令:
: q 在未作修改的情况下退出; : q! 放弃所有修改,退出编辑程序。
保存并退出则可以讲两条命令结合起来使用(注意命令顺序,先保存,后退出):
:wq
编辑中的每一行正文都有自己的行号,用下列命令可以移动光标到指定行(效果与 编辑模式 下的 ngg
或 nG
相同):
: n 将光标移到第 n 行
命令模式下,可以规定命令操作的行号范围。数值用来指定绝对行号;字符“.”表示光标所在行的行号;字符符“$”表示正文最后一行的行号;简单的表达式,例如“.+5”表示当前行往下的第 5 行。例如:
:345 将光标移到第 345 行 :345w file 将第 345 行写入 file 文件 :3,5w file 将第 3 行至第 5 行写入 file 文件 :1,.w file 将第 1 行至当前行写入 file 文件 :.,$w file 将当前行至最后一行写入 file 文件 :.,.+5w file 从当前行开始将 6 行内容写入 file 文件 :1,$w file 将所有内容写入 file 文件,相当于 :w file 命令
在命令模式下,允许从文件中读取正文,或将正文写入文件。例如:
:w 将编辑的内容写入原始文件,用来保存编辑的中间结果 :wq 将编辑的内容写入原始文件并退出编辑程序(相当于 ZZ 命令) :w file 将编辑的内容写入 file 文件,保持原有文件的内容不变 :a,bw file 将第 a 行至第 b 行的内容写入 file 文件 :r file 读取 file 文件的内容,插入当前光标所在行的后面 :e file 编辑新文件 file 代替原有内容 :f file 将当前文件重命名为 file :f 打印当前文件名称和状态,如文件的行数、光标所在的行号等
在 编辑模式 讲过字符串的搜索,此处的 命令模式 也可以进行字符串搜索,给出一个字符串,可以通过搜索该字符串到达指定行。如果希望进行正向搜索,将待搜索的字符串置于两个 /
之间;如果希望反向搜索,则将字符串放在两个 ?
之间。例如:
:/str/ 正向搜索,将光标移到下一个包含字符串 str 的行 :?str? 反向搜索,将光标移到上一个包含字符串 str 的行 :/str/w file 正向搜索,并将第一个包含字符串 str 的行写入 file 文件 :/str1/,/str2/w file 正向搜索,并将包含字符串 str1 的行至包含字符串 str2 的行写
当给Vim指定搜索字符串时,可以包含具有特殊含义的字符。包含这些特殊字符的搜索字符串称为正则表达式(Regular Expressions)。例如,要搜索一行正文,这行正文的开头包含 struct
字。下面的命令做不到这一点:
:/struct/
因为它只找出在行中任意位置包含 struct
的第一行,并不一定在行的开始包含 struct
。解决问题的办法是在搜索字符串前面加上特殊字符^:
:/^struct/
^
字符比较每行开头的字符串。所以上面的命令表示:找出以字符串 struct
开头的行。
也可以用类似办法在搜索字符串后面加上表示行的末尾的特殊字符 $
来找出位于行末尾的字:
:/^struct/
下表给出大多数特殊字符和它们的含义:
^ 放在字符串前面,匹配行首的字; $ 放在字符串后面,匹配行尾的字; \< 匹配一个字的字头; \> 匹配一个字的字尾; . 匹配任何单个正文字符; [str] 匹配 str 中的任何单个字符; [^str] 匹配任何不在 str 中的单个字符; [a-b] 匹配 a 到 b 之间的任一字符; * 匹配前一个字符的 0 次或多次出现; \ 转义后面的字符。
简单介绍这么多,正则表达式知识可以参考
《正则表达式30分钟入门》:http://deerchao.net/tutorials/regex/regex.htm
另外,进阶的Vim正则表达式还有对Magic 模式的介绍,可以参考
《Vim正则表达式详解》:
http://blog.csdn.net/salc3k/article/details/8222397
利用 :s
命令可以实现字符串的替换。具体的用法包括:
:%s/str1/str2/ 用字符串 str2 替换行中首次出现的字符串 str1 :s/str1/str2/g 用字符串 str2 替换行中所有出现的字符串 str1 :.,$ s/str1/str2/g 用字符串 str2 替换正文当前行到末尾所有出现的字符串 str1 :1,$ s/str1/str2/g 用字符串 str2 替换正文中所有出现的字符串 str1 :g/str1/s//str2/g 功能同上 :m,ns/str1/str2/g 将从m行到n行的str1替换成str2
从上述替换命令可以看到:
`g` 放在命令末尾,表示对搜索字符串的每次出现进行替换,不止匹配每行中的第一次出现;不加 `g`,表示只对搜索字符串的首次出现进行替换;`g` 放在命令开头,表示对正文中所有包含搜索字符串的行进行替换操作;
`s` 表示后面跟着一串替换的命令;
`%` 表示替换范围是所有行,即全文。
另外一个实用的命令,在Vim中统计当前文件中字符串 str1
出现的次数,可用替换命令的变形:
:%s/str1/&/gn
在命令模式下,同样可以删除正文中的内容。例如:
:d 删除光标所在行 :3d 删除 3 行 :.,$d 删除当前行至正文的末尾 :/str1/,/str2/d 删除从字符串 str1 到 str2 的所有行 :g/^\(.*\)$\n\1$/d 删除连续相同的行,保留最后一行 :g/\%(^\1$\n\)\@<=\(.*\)$/d 删除连续相同的行,保留最开始一行 :g/^\s*$\n\s*$/d 删除连续多个空行,只保留一行空行 :5,20s/^#//g 删除5到20行开头的 # 注释
总之,Vim的初级删除命令是用 d
,高级删除命令可以用 正则替换 的方式执行。
Vim 在编辑某个文件时,会另外生成一个临时文件,这个文件的名称通常以 .
开头,并以 .swp
结尾。Vim 在正常退出时,该文件被删除,若意外退出,而没有保存文件的最新修改内容,则可以使用恢复命令 :recover
来恢复文件,也可以在启动Vim时用 -r
选项。
为控制不同的编辑功能,Vim 提供了很多内部选项。利用 :set
命令可以设置选项。基本语法为:
:set option 设置选项 option
常见的功能选项包括:
autoindent 设置该选项,则正文自动缩进 ignorecase 设置该选项,则忽略规则表达式中大小写字母的区别 number 设置该选项,则显示正文行号 ruler 设置该选项,则在屏幕底部显示光标所在行、列的位置 tabstop 设置按 Tab 键跳过的空格数。例如 :set tabstop=n,n 默认值为 8 mk 将选项保存在当前目录的 .exrc 文件中
当处于编辑的对话过程中时,可能需要执行一些Linux命令。如果需要保存当前的结果,退出编辑程序,再执行所需的Linux命令,然后再回头继续编辑过程,就显得十分累赘。如果能在编辑的环境中运行Linux命令就要省事得多。在Vim中,可以用下面的命令来做到这一点:
:!shell_command 执行完 shell_command 后回到Vim
这称为Shell切换。它允许执行任何可以在标准的Shell提示符下执行的命令。当这条命令执行完毕,控制返回给编辑程序。又可以继续编辑对话过程。
普通的Vim模式,打开一个Vim程序只能查看一个文件,如果想同时查看多个文件,就需要用到Vim分屏与标签页功能。
Vim的分屏,主要有两种方式:上下分屏(水平分屏)和左右分屏(垂直分屏),在命令模式分别敲入以下命令即可:
:split(可用缩写 :sp) 上下分屏; :vsplit(可用缩写 :vsp) 左右分屏。
另外,也可以在终端里启动vim时就开启分屏操作:
vim -On file1 file2... 打开 file1 和 file2 ,垂直分屏 vim -on file1 file2... 打开 file1 和 file2 ,水平分屏
理论上,一个Vim窗口,可以分为多个Vim屏幕,切换屏幕需要用键盘快捷键,命令分别有:
Ctrl+w+h 切换到当前分屏的左边一屏; Ctrl+w+l 切换到当前分屏的右边一屏; Ctrl+w+j 切换到当前分屏的下方一屏; Ctrl+w+k 切换到当前分屏的上方一屏。
即键盘上的h,j,k,l
四个Vim专用方向键,配合Ctrl
键和w
键(window
的缩写),就能跳转到目标分屏。另外,也可以直接按 Ctrl+w+w
来跳转分屏,不过跳转方向则是在当前Vim窗口所有分屏中,按照逆时针
方向跳转。
下面是改变尺寸的一些操作,主要是高度,对于宽度你可以使用 [Ctrl+W <]
或是 [Ctrl+W >]
,但这可能需要最新的版本才支持。
Ctrl+W = 让所有的屏都有一样的高度; Ctrl+W + 增加高度; Ctrl+W - 减少高度。
Vim的标签(Tab)页,类似浏览器的标签页,一个标签页打开一个Vim的窗口,一个Vim的窗口可以支持N个分屏。
在Vim中新建一个标签的命令是:
:tabnew
如果要在新建标签页的同时打开一个文件,则可以在命令后面直接附带文件路径:
:tabnew filename
Vim中的每个标签页有一个唯一的数字序号,第一个标签页的序号是0
,从左向右依次加一。关于标签页有一系列操作命令,简介如下:
:tN[ext] 跳转到上一个匹配的标签 :tabN[ext] 跳到上一个标签页 :tabc[lose] 关闭当前标签页 :tabdo 为每个标签页执行命令 :tabe[dit] 在新标签页里编辑文件 :tabf[ind] 寻找 'path' 里的文件,在新标签页里编辑之 :tabfir[st] 转到第一个标签页 :tabl[ast] 转到最后一个标签页 :tabm[ove] N 把标签页移到序号为N位置 :tabnew [filename] 在新标签页里编辑文件 :tabn[ext] 转到下一个标签页 :tabo[nly] 关闭所有除了当前标签页以外的所有标签页 :tabp[revious] 转到前一个标签页 :tabr[ewind] 转到第一个标签页
Vim可以与许多外部程序集成,功能十分强大,比如 diff
, ctags
, sort
, xxd
等等,下面选取几个简单介绍一下。
Linux命令 diff
用来对比两个文件的内容,不过对比结果显示在终端里,可读性比较差。结合Vim,在终端里可以直接输入命令 vimdiff
,后面跟两个文件名作为参数:
vimdiff file1 file2
即可在Vim里分屏显示两个文件内容的对比结果,对文件内容差异部分进行高亮标记,还可以同步滚动两个文件内容,更可以实时修改文件内容,方便程度和用户体验大大提高。
vimdiff a.txt b.txt
如果直接给 -d
选项是一样的
vim -d a.txt b.txt
除了在终端里开启vimdiff 功能,也可以在打开Vim后,在Vim的命令模式输入相关命令来开启 vimdiff
功能:
:diffsplit abc.txt
如果你现在已经开启了一个文件,想Vim帮你区分你的文件跟 abc.txt
有什么区别,可以在Vim中用 diffsplit
的方式打开第二个文件,这个时 候Vim会用 split
(分上下两屏)的方式开启第二个文件,并且通过颜色,fold
来显示两个文件的区别
这样Vim就会用颜色帮你区分开2个文件的区别。如果文件比较大(源码)重复的部分会帮你折叠起来。
:diffpatch filename
通过 :diffpatch
你的patch的文件名,就可以以当前文件加上你的patch来显示。vim会split一个新的屏,显示patch后的信息并且用颜色标明区别。
如果不喜欢上下对比,喜欢左右(比较符合视觉)可以在前面加 vert
,例如:
:vert diffsplit abc.txt :vert diffpatch abc.txt
看完diff,用 :only
回到原本编辑的文件,觉得diff的讨厌颜色还是在哪里,只要用 :diffoff
关闭就好了。
还有个常用的diff中的就是 :diffu
,这个是 :diffupdate
的简写,更新的时候用。
Vim的diff
功能显示效果如下所示:
图片来自 http://www.2cto.com/net/201608/536924.html
Linux命令 sort
可以对文本内容进行按行中的字符比较、排序,但在终端里使用 sort
命令处理文件,并不能实时查看文件内容。具体用法请自查手册。
vim+xxd
是Linux下最常用的二进制文本编辑工具,xxd
其实是Vim外部的一个转换程序,随Vim一起发布,在Vim里调用它来编辑二进制文本非常方便。
首先以二进制模式在终端里打开一个文件:
vim -b filename
Vim 的 -b
选项是告诉 Vim 打开的是一个二进制文件,不指定的话,会在后面加上 0x0a
,即一个换行符。
然后在Vim的命令模式下键入:
:%!xxd
即可看到二进制模式显示出来的文本,看起来像这样:
0000000: 1f8b 0808 39d7 173b 0203 7474 002b 4e49 ....9..;..tt.+NI 0000010: 4b2c 8660 eb9c ecac c462 eb94 345e 2e30 K,......b..4^.0 0000020: 373b 2731 0b22 0ca6 c1a2 d669 1035 39d9 7;'1.".....i.59
然后就可以在二进制模式下编辑该文件,编辑后保存,然后用下面命令从二进制模式转换到普通模式:
:%!xxd -r
另外,也可以调整二进制的显示模式,默认是 2 个字节为一组,可以通过 g
参数调整每组字节数:
:%!xxd -g 1 表示每1个字节为1组 :%!xxd -g 2 表示每2个字节为1组(默认) :%!xxd -g 4 表示每4个字节为1组
最初安装的Vim功能、特性支持比较少,用起来比较费劲,想要稍微“好用”一点,需做一些初步的配置。Vim的配置主要分为Vim本身特性的配置和外部插件的配置两部分。
Vim的配置是通常是存放在用户主目录的 .vimrc
的隐藏文件中的。就Vim本身特性来说,基础的配置有编程语言语法高亮、缩进设置、行号显示、搜索高亮、TAB键设置、字体设置、Vim主题设置等等,稍微高级一些的有编程语言缩进、自动补全设置等,具体配置项可以自行查资料,全面详细的配置项介绍可以参考:
《Vim Options》:
http://vimcdoc.sourceforge.net/doc/options.html#%27completeopt%27
Vim“编辑器之神”的称号并不是浪得虚名,然而,这个荣誉的背后,或许近半的功劳要归功于强大的插件支持特性,以及社区开发的各种各样功能强大的插件。
平时开发人员常用插件主要是目录(文件)查看和管理、编程语言缩进与自动补全、编程语言Docs支持、函数跳转、项目管理等等,简单配置可以参考下面:
《Vim插件简单介绍》:
http://blog.segmentfault.com/xuelang/1190000000630547
《手把手教你把Vim改装成一个IDE编程环境(图文)》:
http://blog.csdn.net/wooin/article/details/1858917
《将Vim改造为强大的IDE》:
http://www.cnblogs.com/zhangsf/archive/2013/06/13/3134409.html
当然,这些插件都是拜Vim本身的插件支持特性所赐。Vim为了支持丰富的第三方插件,自身定义了一套简单的脚本开发语言,供程序员自行开发自己所需要的插件,插件开发介绍可以参考:
《Writing Vim Plugins》:
http://stevelosh.com/blog/2011/09/writing-vim-plugins/
请问有时会看到诸如 <C-x> 这样的快捷键,这是什么意思,要怎么按出来呢?
按: Ctrl+C
转载自: https://www.jianshu.com/p/bcbe916f97e1
一、安装 Vim;
二、在命令行中输入 vimtutor 或者 gvimtutor 并阅读;
三、开始日常使用,在遇到问题时使用 :help 命令。
喜欢看中文文档者增加一步: 搜索 vimcdoc ,然后下载并安装中文文档。
1、用vim打开文件 vi 文件路径 2、按字母 i 进入 编辑模式; 3、按 :wq 或者 按 :x 保存退出 ":x"和":wq"的真正区别,如下: :wq 强制性写入文件并退出。即使文件没有被修改也强制写入,并更新文件的修改时间。 :x 写入文件并退出。仅当文件被修改时才写入,并更新文件修改时间,否则不会更新文件修改时间。 编译代码时,在没有修改源文件的情况下,仅仅使用":wq"命令保存文件,源文件会重新编译。 这是因为文件即使没有修改,":wq"强制更新文件的修改时间, 这样会让 make编译整个项目时以为文件被修改过了,然后就得重新编译链接生成可执行文件。
楼主 学习 centos 命令时,再网上 找了些 shell 命令,复制到 终端运行 时 ,有时会出现,莫名其妙的错误。
有时候报错,命令中 有302 ,有时候 报错 找不到 命令。
看上去 感觉 sh 命令 很正确啊。
其实 可能是 空格 有问题,-破折号,中英文,还有可能是 看不见的 特殊 字符。
在使用SSH客户端进行连接管理的时候如果长时间不输入命令,服务器会自动断开连接,尤其是利用代理进行SSH连接时情况更突出。
Bad packet length 2165930639. padding error: need -2129036657 block 8 mod 7 ssh_dispatch_run_fatal: Connection to UNKNOWN: message authentication code incorrect
——————————————————————————-
这样连接上去,利用代理,会经常掉线。
后来,我提权 ,用sudo ,以root 身份运行就 不会掉线了,奇怪了啊。
记得 用 root 身份连接 +
打开服务器 /etc/ssh/sshd_config,我在最后增加一行
ClientAliveInterval 60
ClientAliveCountMax 1
(可能我在 ~/.ssh/ssh_config 文件里配置了
TCPKeepAlive yes
ServerAliveInterval 30
前一个参数是说要保持连接,后一个参数表示每过30秒发一个数据包到服务器表示“我还活着”。可能这地方也需要配置下吧。)
这样实际使用中 的确 可以 保持 很长的连接。
(操作 环境 mac下 使用root账户 操作 SSH , 并以root用户登入到远程 centos 主机中 )
重要信息:经过测试:
# 在 ~/.ssh/ssh_config 文件(即当前用户的SSH配置文件中) 配置了下面参数 #1、保持 tcp 连接 TCPKeepAlive yes #2、每过30秒发一个数据包到服务器表示"我还活着" ServerAliveInterval 30 # 经过测试,用本机当前用户 进行 SSH远程连接操作 也没有问题。不会掉线了。
其他方法也有,比如用 screen 恢复 ssh 会话。
*********************************************************************
后面提到的方法都已经单独试过了,感觉 没有 效果。
——————————————————————————-
针对这种情况,我在网上搜集了可以让 SSH 保持连接的方法与大家分享
在服务器端, 可以让服务器发送“心跳”信号测试提醒客户端进行保持连接
通过修改 sshd 的配置文件,能够让 SSH Server 发送“心跳”信号来维持持续连接,下面是设置的内容
打开服务器 /etc/ssh/sshd_config,我在最后增加一行
ClientAliveInterval 60
ClientAliveCountMax 1
这 样,SSH Server 每 60 秒就会自动发送一个信号给 Client,而等待 Client 回应,(注意:是服务器发心跳信号,不是客户端,这个有别于一些 FTP Client 发送的 KeepAlives 信号哦~~~),如果客户端没有回应,会记录下来直到记录数超过 ClientAliveCountMax 的值时,才会断开连接。
如果你没有服务器端管理权限, 在客户端进行设置也可以实现
只要在/etc/ssh/ssh_config文件里加两个参数就行了
1 TCPKeepAlive yes
2 ServerAliveInterval 300
前一个参数是说要保持连接,后一个参数表示每过5分钟发一个数据包到服务器表示“我还活着”
如果你没有root权限,修改或者创建~/.ssh/ssh_config也是可以的
在这种方法中, 如果你只想针对某一个ssh连接进行持续, 你可以将上述配置文件复制一下进行修改然后在连接的时候使用 -F参数进行配置文件的指定。 当然因为只需要修改两个参数, 你也可以直接在连接命令中进行设定即:
ssh -o TCPKeepAlive=yes -o ServerAliveInterval=300 [email protected] -p 12345678
——————————————————————————-
有可能是 网络问题,杀毒软件导致 端口被占,收到的 数据包 出错
Found the cause for my problem by accident. I tried to use an old trick and started a System Recovery to undo my Git installation. It failed because of my Virus Scanner. After uninstalling Bitdefender Antivirus Free Edition it worked. Incoming SSH2 messages were blocked (got Windows 8 Pro) which caused the bad packet length error. Anyway, thanks for your support!
——————————————————————————–
有可能是 一开始 验证密钥文件 时,密钥文件 默认名字可能是其他服务器的密钥 ,所以尽量重命名,指定服务器需要的密钥
save the keys in C:\Users\myUserName\.ssh\keyName
Your local ssh command would look for ssh keys in %HOME%\.ssh\id_rsa(.pub).
So you need to either:
rename the local files representing your ssh (public and private) keys
or reference those through a %HOME%\.ssh\config which can reference the exact name of your private key (with an IdentityFile directive).
Host gitlab
user git
hostname your.gitlab.server.com
IdentityFile C:\user\YourUsername\.ssh\keyName
偶尔从网上看到不错的源码,想研究下,不幸编译时遇到
“错误:程序中有游离的’\240”\302′”之类的错误,
首先,编译器提示的\xxx,都是8进制的编码,使用sed做下全文替换,命令如下:
sed -i 's/\o240\|\o302//g' filename.cpp
\o指定用8进制编码,中间的\|是指要同时替换多个,这样就OK了。
刚才给你实验了一下:
sed 's/\x20//g' test.txt # 这个命令表示将test.txt中,字符为0x20的字符替换为空。 # s表示替换,x20表示16进制0x20实际上空格,另外的空的表示替换为空,g表示全部。 # 实际就是把test.txt中的全部空格删除掉。
sed 's/aaa/bbb/g' test.txt # 将aaa替换为bbb。
这一般是“”,“”、,、;等符号使用错误,有时甚至是空格。
怎么解决呢?
很简单就是把他们一一改正,但很多不容易找怎么办?
可以使用linux 下的od命令加上重定向,
od详解:
Linux指令:od
# 示例用法: od -c hello
od命令
用户通常使用od命令查看特殊格式的文件内容。通过指定该命令的不同选项可以以十进制、八进制、十六进制和ASCII码来显示文件。
语法:od [选项] 文件… 命令中各选项的含义: - A 指定地址基数,包括: d 十进制 o 八进制(系统默认值) x 十六进制 n 不打印位移值 - t 指定数据的显示格式,主要的参数有: c ASCII字符或反斜杠序列 d 有符号十进制数 f 浮点数 o 八进制(系统默认值为02) u 无符号十进制数 x 十六进制数 除了选项c以外的其他选项后面都可以跟一个十进制数n,指定每个显示值所包含的字节数。 说明:od命令系统默认的显示方式是八进制,这也是该命令的名称由来(Octal Dump)。但这不是最有用的显示方式,用ASCII码和十六进制组合的方式能提供更有价值的信息输出。
例如:
1.
qust@qust-K42JZ:~/test$ gcc get_ip.c -o get_ip get_ip.c: 在函数‘main’中: get_ip.c:32:1: 错误: 程序中有游离的‘\302’ get_ip.c:32:1: 错误: 程序中有游离的‘\240’ get_ip.c:36:1: 错误: 程序中有游离的‘\302’ get_ip.c:36:1: 错误: 程序中有游离的‘\240’
2.我们在终端中用 od -c get_ip.c > log.txt 命令将get_ip.c的内容已以 ASCII字符或反斜杠序列 输出到log.txt 中
3.查看log.txt内容
0000000 # i n c l u d e < s t d l i b 0000020 . h > \n # i n c l u d e < s t 0000040 r i n g . h > \n # i n c l u d e 0000060 < s y s / s o c k e t . h > \n 0000100 # i n c l u d e < s y s / i o 0000120 c t l . h > \n # i n c l u d e 0000140 < n e t / i f . h > \n # i n c l 0000160 u d e < s t d i o . h > \n # i 0000200 n c l u d e < n e t i n e t / 0000220 i n . h > \n # i n c l u d e < 0000240 a r p a / i n e t . h > \n \n i n 0000260 t 302 240 m a i n ( ) \n { \n i n t 302 0000300 240 i = 0 ; \n i n t 302 240 s o c k f 0000320 d ; \n s t r u c t 302 240 i f c o n 0000340 f i f c o n f ; \n u n s i g n 0000360 e d 302 240 c h a r 302 240 b u f [ 5 1 0000400 2 ] ; \n s t r u c t 302 240 i f r e 0000420 q * i f r e q ; \n / / 345 210 235 345 0000440 247 213 345 214 226 i f c o n f \n i f c o 0000460 n f . i f c _ l e n = 5 1 2 ; 0000500 \n i f c o n f . i f c _ b u f 0000520 = b u f ; \n i f 302 240 ( ( s o c 0000540 k f d = s o c k e t ( A F _ 0000560 I N E T , S O C K _ D G R A M , 0000600 0 ) ) < 0 ) \n { \n p e r r o r ( 0000620 " s o c k e t " ) ; \n e x i t ( 0000640 1 ) ; \n } \n i o c t l ( s o c k 0000660 f d , S I O C G I F C O N F , & 0000700 i f c o n f ) ; 302 240 / / 350 216 267 345 0000720 217 226 346 211 200 346 234 211 346 216 245 345 217 243 344 277 0000740 241 346 201 257 \n / / 346 216 245 344 270 213 346 235 245 0000760 344 270 200 344 270 252 344 270 200 344 270 252 347 232 204 350 0001000 216 267 345 217 226 I P 345 234 260 345 235 200 \n i f 0001020 r e q = ( s t r u c t 302 240 i f r 0001040 e q * ) b u f ; \n f o r 302 240 ( i 0001060 = ( i f c o n f . i f c _ l e n 0001100 / s i z e o f 302 240 ( s t r u c t 0001120 302 240 i f r e q ) ) ; i > 0 ; 0001140 i - - ) \n { \n / / i f ( i f r 0001160 e q - > i f r _ f l a g s = = 0001200 A F _ I N E T ) { / / f o r 0001220 i p v 4 \n p r i n t f ( " n a 0001240 m e = % s \ n " , i f r 0001260 e q - > i f r _ n a m e ) ; \n p 0001300 r i n t f ( " l o c a l a d d 0001320 r = % s \ n " , i n e t _ 0001340 n t o a ( ( ( s t r u c t 302 240 s 0001360 o c k a d d r _ i n * ) & ( i f 0001400 r e q - > i f r _ a d d r ) ) - 0001420 > s i n _ a d d r ) ) ; \n i f r 0001440 e q + + ; \n / / } \n } \n r e t 0001460 u r n 302 240 0 ; \n } \n \n 0001473
这样我们就可以看到游离的’\200′ ‘\240’ 等在哪了。
让我们先来了解一下端口转发的概念吧。我们知道,SSH 会自动加密和解密所有 SSH 客户端与服务端之间的网络数据。但是,SSH 还同时提供了一个非常有用的功能,这就是端口转发。它能够将其他 TCP 端口的网络数据通过 SSH 链接来转发,并且自动提供了相应的加密及解密服务。这一过程有时也被叫做“隧道”(tunneling),这是因为 SSH 为其他 TCP 链接提供了一个安全的通道来进行传输而得名。例如,Telnet,SMTP,LDAP 这些 TCP 应用均能够从中得益,避免了用户名,密码以及隐私信息的明文传输。而与此同时,如果您工作环境中的防火墙限制了一些网络端口的使用,但是允许 SSH 的连接,那么也是能够通过将 TCP 端口转发来使用 SSH 进行通讯。总的来说 SSH 端口转发能够提供两大功能:
1、加密 SSH Client 端至 SSH Server 端之间的通讯数据。
2、突破防火墙的限制完成一些之前无法建立的 TCP 连接。
如上图所示,使用了端口转发之后,TCP 端口 A 与 B 之间现在并不直接通讯,而是转发到了 SSH 客户端及服务端来通讯,从而自动实现了数据加密并同时绕过了防火墙的限制。
在选择端口号时要注意非管理员帐号是无权绑定 1-1023 端口的,所以一般是选用一个 1024-65535 之间的并且尚未使用的端口号即可。
假设:
墙内客户端 A 128.128.128.128
墙外代理服务器 B 138.138.138.138
目标服务器 C 158.158.158.158
如果 A不能直接访问C ,B能访问C , A能访问B。
可以采用 本地端口转发:
绑定A上的一个端口如2233 ,A向B发起建立SSH隧道连接请求,然后B再访问 C上的端口如5566
这样:访问A上的2233端口 就等于 在访问 C上5566端口
# root@root@B的IP地址 以root用户 登录 B 服务器 #-v 冗详模式. 使打印关于运行情况的调试信息. 在调试连接, 认证和配置问题时非常有用. #并联的 -v 选项能够增加冗详程度. 最多为三个. #-C 要求进行数据压缩 (包括 stdin, stdout, stderr以及转发X11和TCP/IP连接的数据) #-L port:host:hostport 将本地机[主机A]的某个端口[port]转发到远端指定机器[主机C别名host]的指定端口[hostport] # 工作原理是这样的,本地机器[主机A]上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, # 该连接就经过安全通道转发出去, 同时远程主机[主机B]和 host[主机C] 的 hostport 端口建立连接. # 可以在配置文件中指定端口的转发. 只有 root 才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport ssh -v -C -L 2233:C的IP地址:5566 root@B的IP地址 -p B的ssh端口号
那么这个端口转发可以被其他机器使用么?比如能否新增加一台 [主机X] 来直接连接 [主机A] 的 2233 端口?答案是不行的,在主流 SSH 实现中,本地端口转发绑定的是 lookback 接口,这意味着只有 localhost 或者 127.0.0.1 才能使用本机的端口转发 , 其他机器发起的连接只会得到“ connection refused. ”。好在 SSH 同时提供了 GatewayPorts 关键字,我们可以通过指定它与其他机器共享这个本地端口转发。
ssh -g -L 主机A的端口如5901:主机C:主机C的端口如5901 通过SSH连接的主机B
特殊情况下:C的IP地址:5566 可以变成 localhost:5566
localhost:5566 是针对 中间的代理服务器 来说的
这相当于A访问自己的2233端口时 等价于 直接访问B内部的5566端口[若5566端口没有暴露给别的主机,就可规避B上的防火墙]
ssh -v -C -L 2233:localhost:5566 root@B的IP地址 -p B的ssh端口号
假设:
墙内客户端 A 128.128.128.128
墙外代理服务器 B 138.138.138.138
目标服务器 C 158.158.158.158
如果 A不能直接访问C ,B能访问C , B能访问A。
可以采用 远程端口转发:
绑定A上的一个端口如2233 ,B向A发起建立SSH隧道连接请求,然后B再访问C上的端口如5566
这样:访问A上的2233端口 就等于 在访问 C上5566端口
#-R port:host:hostport 将客户机[主机A]的某个端口[port]转发到远端指定机器[主机C别名host]的指定端口[hostport] # 工作原理是这样的, 远程主机[主机A]上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, # 该连接就经过安全通道转向出去, 同时本地主机[主机B]和 host[主机C] 的 hostport 端口建立连接. # 可在配置文件中指定端口的转发.只有root登录远程主机[主机A]才能转发特权端口. # IPv6 地址用另一种格式说明: port/host/hostport ssh -v -C -R 2233:C的IP地址:5566 root@A的IP地址 -p A的ssh端口号
特殊情况下:C的IP地址:5566 可以变成 localhost:5566
localhost:5566 是针对 中间的代理服务器 来说的
这相当于A访问自己的2233端口时 等价于 直接访问B内部的5566端口[若5566端口没有暴露给别的主机,就可规避B上的防火墙]
ssh -v -C -R 2233:localhost:5566 root@A的IP地址 -p A的ssh端口号
总之,port:host:hostport 这三个参数,是按照,实际操作中,谁是代理服务器,来进行区分配置的。
恩,动态转发,听上去很酷。当你看到这里时,有没有想过我们已经讨论过了本地转发,远程转发,但是前提都是要求有一个固定的应用服务端的端口号,例如前面例子中的 主机C 的 5566 端口。那如果没有这个端口号怎么办?等等,什么样的应用会没有这个端口号呢?嗯,比如说用浏览器进行 Web 浏览,比如说 MSN 等等。
当我们在一个不安全的 WiFi 环境下上网,用 SSH 动态转发来保护我们的网页浏览及 MSN 信息无疑是十分必要的。让我们先来看一下动态转发的命令格式:
1
|
$ ssh -D < local port> < SSH Server> |
例如:
1
|
$ ssh -D 7001 < SSH Server> |
似乎很简单,我们选择了 7001 作为本地的端口号,其实在这里 SSH 是创建了一个 SOCKS 代理服务。来看看帮助文档中对 -D 参数的描述:
1
2
3
4
5
6
7
8
9
|
-D port This works by allocating a socket to listen to port on the local side, and whenever a connection is made to this port, the con- nection is forwarded over the secure channel, and the applica- tion protocol is then used to determine where to connect to from the remote machine. Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh will act as a SOCKS server. Only root can forward privileged ports. Dynamic port forwardings can also be specified in the configuration file. |
之后的使用就简单了,我们可以直接使用 localhost:7001 来作为正常的 SOCKS 代理来使用,直接在浏览器或 MSN 上设置即可。在 SSH Client 端无法访问的网站现在也都可以正常浏览。而这里需要值得注意的是,此时 SSH 所包护的范围只包括从浏览器端(SSH Client 端)到 SSH Server 端的连接,并不包含从 SSH Server 端 到目标网站的连接。如果后半截连接的安全不能得到充分的保证的话,这种方式仍不是合适的解决方案。
好了,让我们来看最后一个例子 – X 协议转发。
我们日常工作当中,可能会经常会远程登录到 Linux/Unix/Solaris/HP 等机器上去做一些开发或者维护,也经常需要以 GUI 方式运行一些程序,比如要求图形化界面来安装 DB2/WebSphere 等等。这时候通常有两种选择来实现:VNC 或者 X 窗口,让我们来看看后者。
使用 X 窗口通常需要分别安装:X Client 和 X Server 。在本例中我们的 X Client 就是所访问的远程 Linux/Unix/Solaris/HP,而我们的 X Server 则是发起访问的本地机器(例如你面前正在使用的笔记本或台式机)。把 X Client 端的 X 窗口显示在 X Server 端需要先行在 X Client 端指定 X Server 的位置,命令格式如下:
1
|
export DISPLAY=< X Server IP>:< display #>.< virtual #> |
例如:
1
|
export DISPLAY=myDesktop:1.0 |
然后直接运行 X 应用即可,X 窗口就会自动在我们的本地端打开。
一切运行正常,但是,这时候 IT 部门突然在远程 Linux/Unix/Solaris/HP 前面加了一道防火墙。非常不幸的是,X 协议并不在允许通过的列表之内。怎么办?只能使用 VNC 了么?不,其实只要使用了 SSH 端口转发即可通过,同时也对 X 通讯数据做了加密,真是一举两得。(当然,使用此方法前最好先咨询相关 IT 部门是否符合相应的安全条例,以免造成违规操作。)
建立命令也很简单,直接从本地机器(X Server 端)发起一个如下的 SSH 连接即可:
1
|
$ ssh -X < SSH Server> |
建立连接之后就可以直接运行远程的 X 应用。注意建立 X 转发之后会自动设置 DISPLAY 环境变量,通常会被设置成localhost:10.0
,我们无需也不应该在连接之后再进行修改此环境变量。
一个比较常见的场景是,我们的本地机器是 Windows 操作系统,这时可以选择开源的 XMing 来作为我们的 XServer,而 SSH Client 则可以任意选择了,例如 PuTTY,Cygwin 均可以配置 访问 SSH 的同时建立 X 转发。
至此,我们已经完成了本地端口转发,远程端口转发,动态端口转发以及 X 转发的介绍。回顾起来,总的思路是通过将 TCP 连接转发到 SSH 通道上以解决数据加密以及突破防火墙的种种限制。对一些已知端口号的应用,例如 Telnet/LDAP/SMTP,我们可以使用本地端口转发或者远程端口转发来达到目的。动态端口转发则可以实现 SOCKS 代理从而加密以及突破防火墙对 Web 浏览的限制。对于 X 应用,无疑是 X 转发最为适用了。虽然每一部分我们都只是简单的介绍了一下,但如果能灵活应用这些技巧,相信对我们的日常生活 / 工作也是会有所帮助的。