<audio id="audio" title="轻松话题（二） | 给你分享我的工作百宝箱" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/87/79/871d7c37a5203abbae70af90dcda0879.mp3"></audio>

你好，我是Chrono。

今天，我再来说点C++之外的话题。我来聊聊我的工作方式，给你介绍一下我用的开发环境，有快捷键、配置脚本、常用命令什么的。算不上什么“高效技巧”，但是也能从小处提高工作效率，希望能给你一点借鉴。

## Linux

我主要是在Linux上写程序，经常要登录到内部的服务器，但我常用的笔记本或者台式机上装的还是Windows，所以就需要有一个“趁手”的客户端。

Windows上有很多这样的软件，最早我用的是PuTTY，但其他很多同事用的是XShell。不过，现在的我已经都不用这些了。

你一定想知道，难道还有什么比PuTTY、XShell更好更强大的远程终端吗？

要说有也算有，要说没有也算是没有。

因为，现在我就把Linux操作系统当成终端机来使用，就用它内置的Terminal、ssh命令来实现远程登录。

具体的做法也很简单，安装一个VirtualBox，再最小化安装一个Ubuntu，就可以了。

这么做的好处在哪里呢？

首先，这个环境完全是免费的，不需要注册或者破解。其次，它本身就是Linux，与开发环境相同，可以用来在本地做试验、“练手”。再次，Linux里有非常丰富的工具可以下载安装，能够随心所欲地定制环境，用起来非常舒心。

当然，把Linux转换成一个高效的终端，还是需要一点点“技巧”的，接下来，我就跟你说说我的做法，要点就是“**全程键盘操作**”。

第一个，用“Ctrl+Alt+T”可以直接打开命令行窗口，而不必用鼠标去点图标，然后用“Ctrl+Shift+T”可以开新标签页，这样就可以很方便地实现多窗口登录，不会像某些软件那样有数量的限制。

另外，我选择的是Ubuntu 14.04，在这个版本里，可以用鼠标右键点标签页直接改标题名，区分不同的窗口，即使开多个标签也可以轻松管理（但这个功能在后来的16.04、18.04却给去掉了，只能额外写Shell脚本来实现，有那么一点不爽）。

第二个，修改Shell的配置文件“.bashrc”或者是“.profile”，在里面加上一行“set -o vi”。

```
#.bashrc
set -o vi

```

这样，你就可以在命令行里实现vi操作了，按一下ESC键，就进入到了vi模式，可以用“/”快速查找之前的历史命令，而不必每次都要敲完整的命令。

比如说，之前输入了一条命令“`ssh chrono@10.1.1.25`”登录服务器，那么，下次再登录时就没有必要再敲一遍了，只要按ESC，然后输入“/25”，回车，Linux就可以帮你找到上次的这条命令。这时，你就可以轻松愉快地登录了。

用Linux作为终端的唯一一个缺点，是它无法自动填写登录密码，每次都要手动敲，这个的确比较烦人。所以，只能把登录密码尽量改得简单好输入，最好是键盘上的固定模式（比如设置成“qazwsx”），这样就可以在1秒内完成。

## Vim

写代码就要用到编辑器，在Windows里，常用的有VS Code、Sublime，等等，而在Linux里，最佳的选择可能就是Vim了。

说是Vim，但我更愿意称之为vi。一方面是早期的使用习惯（我最早用的是AIX，上面只有vi，而不是Vim），另一个更重要的原因是可以少打一个字符。可不要小看了这一点效率的提升，想想每天你要说多少次、用多少次vi吧。

有的人可能还是习惯在Windows上的编辑器里写代码，然后通过某种方式上传到Linux，再编译和运行。我个人觉得这种做法不太可取，既然是Linux开发，就应该全程在Linux上工作，而且很多时候会现场调试，不可能有那么合适的编辑器。

所以，尽早抛弃“窗口+鼠标”式编辑器，强迫自己只用vi，就可以尽快熟悉vi的各种操作，让你在Linux上“运指如飞”。

另外，你可能知道，vi也有很多的插件，比如ctags，搭配上众多的插件会让vi更“现代化”。但对于服务器开发来说，还是那个问题：不是每台服务器都会给你配置得那么完善的。与其倒腾那些“花里胡哨”的插件，不如“离开舒适区”，练好vi的基本功，到哪里都能吃得开。

最基本的vi操作，我就不多谈了，网上一搜一大堆，我来说几个写代码时比较实用的命令。

1.“:tabnew”，新建一个编辑窗口，也就是支持多标签操作，多个标签可以用“gt”切换。

2.“Ctrl+V”“Shift+V”的整列整行选择，然后就可以用“x”剪切、“p”粘贴。

“Ctrl+V”的列选择功能还有一个衍生的方便技巧：选择多列后按“I”，再输入“//”，按ESC，就可以在每行前面都插入“//”，轻松地实现大段代码的工整注释。

3.“Ctrl+P”是vi内置的“代码补全”功能，对我们程序员来说特别有用。只要写上开头的一两个字符，再按“Ctrl+P”，vi就可以提示出文件里曾经出现的词，这样，在写长名字时，就再也不用害怕了。

不过，vi的“代码补全”功能还是比较弱的，不是基于语法分析，而是简单的文本分词，但我们也不能太苛求。

4.可以随时用“Ctrl+Z”暂停vi，把它放到后台，然后执行各种Shell操作，在需要的时候，只要敲一个“fg”命令，就可以把vi恢复回来。

这在调试的时候非常有用，改改代码，运行一下，看看情况再切回来继续改，不用每次重复vi打开源文件，而且可以保留编辑的“现场”。

除了刚才的这四点操作技巧，想要用好vi，还必须要对它做适当的配置，比如显示行号、控制缩进，等等。下面就是我常用的“.vimrc”，非常短小，基本上我每登录一台新服务器，就会把这个配置复制过去，这样，无论在哪里，vi都会是我熟悉的环境。

```
#.vimrc
set nu
sy on
set ruler
set smartindent shiftwidth=4
set tabstop=4
set expandtab

set listchars=tab:&gt;-,trail:~
set list
colorscheme desert

```

## Git

写完了程序，还要用适当的版本控制系统把它管理起来，否则源码丢失、版本回溯、多人协作等问题会把你弄得焦头烂额。

我最早用的是微软的VSS（Visual Source Safe），后来用过IBM的ClearCase，再后来又用SVN，现在则是Git的“铁杆粉丝”。

Git的好处实在太多了：分布式、轻量级、可离线、开分支成本低……还有围绕着它的GitHub/GitLab等高级团队工作平台，绝对是最先进的版本控制系统。

如果在2020年的今天，你所在的公司还在用SVN这样的“上古”软件，可真的是要考虑一下项目的前景了。

Git有许多高级用法，有的也很复杂，我不可能也没必要把那些讲清楚。所以，我只介绍一个能够简化Git操作的小技巧：**命令别名**。

Git的命令含义明确，但缺点是单词太长，多次操作输入就显得很繁琐，这点就不如SVN命令那么简单明了。好在我们可以在Git的配置文件“.gitconfig”里为这些命令起别名，比如把“status”改成“st”，把“commit”改成“ci”。

下面这个就是我常用的一个Git配置，里面还有个特别的地方是在“diff”的时候使用“vimdiff”，用可视化的方式来比较文件的差异，比原始的“diff”更好。

```
[alias]
st = status
ci = commit
br = branch
co = checkout
au = add -u .
ll = log --oneline --graph
d = difftool
[diff]
tool = vimdiff

```

## GDB

最后来说一下调试工具GDB吧，它应该是Linux程序员最得力的一个帮手了。

标准的GDB是纯命令行式的，但也有一些基于它的图形化工具（比如DDD、Data Display Debugger），但用好GDB命令行调试，还是我们的一项基本素质。

**GDB不仅是一个调试工具，它也是一个学习源码的好工具**。

单纯的源码是静态的，虽然你可以分析它的整体架构，在头脑里模拟出它的工作流程，但计算机实在是太复杂了，内外部环境因素很多，仅靠“人肉分析”很难完全理解它的逻辑。

这个时候，GDB就派上用场了，以调试模式启动，任意设定外部条件，从指定的入口运行，把程序放慢几万倍，细致地观察每个变量的值，跟踪代码的分支和数据的流向，这样走上几个来回之后，再结合源码，就能够对程序的整体情况“了然于胸”。

GDB用得久了，差不多每个人都会有一些自己的心得。我列出一些我觉得能够提高调试效率、最有价值的命令。

- pt：查看变量的真实类型，不受typedef的影响。
- up/down：在函数调用栈里上下移动。
- fin：直接运行到函数结束。
- i b：查看所有的断点信息。
- wh：启动“可视化调试”。这个是我最喜欢的命令，可以把屏幕分成上下两个窗口，上面显示源码，下面是GDB命令输出，不必再用“l”频繁地列出源码了，能够大大提高调试的效率。

## 小结

好了，今天的话题就到这里，简单小结一下我的工作环境，给你一个参考：

1. 我选择Linux虚拟机作为登录服务器的终端，可以很容易开多窗口操作；
1. 我选择Vim作为编辑器，熟记常用命令后写代码也很方便；
1. 我选择Git作为版本管理工具，使用别名来简化命令；
1. GDB是调试C++程序的利器，也可以用来学习源码。

那么，你是否也有一些工作中的实用小技巧呢？欢迎一起来分享。

<img src="https://static001.geekbang.org/resource/image/f6/87/f6b5366fe5a70ba18517aa6bc51f5287.jpg" alt="">
