macOS 效率系列 02: 在终端 Terminal 中运键如飞

2019年8月9日 · 5 years ago

欢迎大家留言或者邮件 justin@justinyan.me 分享你喜欢的效率工具或者效率技巧。

光阴荏苒,日月如梭。

如何把有限的时间和精力用在有意义的事情上是人类无法逃避的问题。作为 macOS daily user,高效用好 macOS 系统及其生态中的各种工具可以让我们少浪费一些生命在无意义的重复劳动中。

关于 macOS 的效率工具网络上已经有非常多的文章可供参考,本系列不过总结一二,希望能对读者有所帮助。

一、Terminal, 终端, Shell

早期的终端

终端(computer terminal)是一个历史遗留下来的名词,早期的终端机大概长这样。这个不是个人电脑,只是一台显示器,接了一个键盘(DEC VT100)。背后有一台巨大的主机,对接很多台终端,这样每个终端就是一个输入输出设备。

今天大家都在用个人电脑(PC),普通用户基本不会遇到多终端共享同一个主机的情况。但也并不是完全没有终端,比如车站的刷卡机就是一台终端机。

车站的终端机

所以现在各种类 Unix 系统——比如 Linux 的各种发行版,和基于 FreeBSD 的 macOS——都在 UI 层虚拟了一个终端。

当你打开虚拟终端的时候,和古老的物理终端一样,会运行一个最基本的人机交互程序,称为 Shell。

在 Shell 中输入一行命令,它就解释执行这一行,然后显示结果。另外 Shell 也支持批量处理命令,需要写一个 Shell 脚本,然后执行它。历史上有多种不同的 Shell:

  • sh: Bourne Shell,由 Steve Bourne 开发,绝大多数 UNIX 系统标配
  • csh: Bill Joy 开发,BSD UNIX 系统标配
  • ksh: David Korn 开发,兼容 sh,并支持 csh 的新功能
  • tcsh: csh 的加强版
  • bash: Bourne Again Shell,GNU 开发的,基本上是所有 Linux 系统默认的 shell 了

想要知道你的系统自带了什么 shell,你可以在终端运行:

cat /etc/shells

macOS 自带的是这些:

/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh

二、Oh My Zsh

除开 Windows 的 cmd.exe,我最早接触终端是在 Linux 系统上,当时用的是 Ubuntu 桌面版。现在大多数人接触 PC 都是从桌面版带 GUI 的操作系统开始,所以相比之下命令行要显得稍微难操作一点。如果有读者朋友觉得命令行操作起来相对困难的话,可以参考著名的《鸟哥的Linux私房菜》这本书。作为入门读物还是非常容易上手的。

接下来我们假定读者朋友们都已经比较熟悉 Shell 操作了。目前多数类 Unix 系统的默认 Shell 都是 Bash,它已经足够用了,但是还不够好用。

目前比较流行的 Shell 是 zshfish。二者各有优劣,我个人使用的而是 zsh

ZSH 称为 Z shell,是基于 sh(Bourne shell)的扩展,包括了 ksh, Bashtcsh等多种 shell 的特性。今年 WWDC 2019 上苹果亦宣布将用 zsh 取代 bash 称为 macOS Catalina 的默认 shell

zsh 的自动拼写纠错,大小写不敏感的自动补全,自带的 where 命令等都非常实用。在 macOS 上用 Bash 试图 cd down[Tab] 的人都应该有所体会。

zsh 还支持各种插件和扩展,开发者可以基于 zsh 实现各种酷炫的命令行体验。Oh My Zsh就是一个开源的项目,也是大多数 zsh 用户的选择。

超过 1350+ 的贡献者为这个项目贡献了 250+ 的插件和 125+ 的主题。

安装起来非常简单,通过 curl 或者按照官网指示安装即可:

sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

oh my zsh 自带的 git 插件简直是开发者的福音。

还有多款主题任君选择: Themes · robbyrussell/oh-my-zsh Wiki

三、 autojump

在 shell 里进行文件夹路径变换我们用的是 cd 命令(change directory)。假如我们有一个层级比较深的路径: ~/Documents/ADir/BDir/CDir/DDir。一般我们需要

cd ~ #或者 cd
cd Documents
cd ADir
cd BDir
cd CDir
cd DDir

这还是我能记得这个路径的前提下。一般情况下我只记得它大概在哪里,所以还得多次 ls 看看是不是在当前目录。

这时候你需要一个无论身处哪个路径都可以轻松跳转过去的 jump 操作

j DDir

这就是 autojump 干的事情。只要 j keyword 就可以到达关键词所在的地方,都不需要记得完整的名字。

autojump 会对你曾经到达过的路径做一个缓存,然后自己计算一个优先级。如果有多个同名文件夹,它会优先匹配最高优先级的那个。如果你觉得这个优先级不对,你可以使用 j -i 或者 j -d 来增加/减少当前目录的权重。

oh my zsh 也提供一个类似效果的插件,叫做 z。github 地址在这里: oh-my-zsh/plugins/z at master · robbyrussell/oh-my-zsh

oh my zsh 除了直接把当前 git 仓库的信息展示在终端之外,还自带许多方便的 git 命令的 aliases,比如:

Alias Command
gaa git add --all
ggp git push origin $(current_branch)

这些 git 命令我们每天都需要打无数次,能用 alias 还是非常方便省事的。

完整的 aliases cheatsheet 可以参考这里: Cheatsheet · robbyrussell/oh-my-zsh Wiki

四、.bash_profile, .profile 和 .zshrc

如果我们不做任何修改,登录 shell 之后的所有配置就是默认的。但是我们通常都需要安装各种工具,这些工具需要前置配置,比如环境变量 PATH。这些东西都保存在 .profile 文件里。类 Unix 系统在登录 shell 的时候一般都会读取 .profile 文件。

如果你在自己的 Home 目录(~) ls -a 一下一般可以看到这几个文件:

.profile
.bash_profile
# 如果装了 zsh 的话
.zshrc

这几个文件的作用是类似的,但是读取顺序不同,其中 .zshrc 只会被 zsh 读取。关于这几个配置文件的顺序大家感兴趣的可以参考这里: .bash_profile vs .bashrc - Abhinav korpal - Medium

一般情况下我会在 Dropbox 里放一个 .bash_profile 文件,然后在多台 Mac 之间共享这个文件,只需使用 ln -s 在 Home 目录创建一个软链。

.bash_profile -> /Users/xxx/Dropbox/bash_profile

这个文件里面我们可以配置 shell 的 locale 信息,比如:

export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LC_ALL=en_US.UTF-8

或者是 Go 的配置:

# Go
export GOPATH=$HOME
export GOPATH=$HOME/go
export GOBIN=$HOME/go/bin

或者是一些常用的但是比较长的命令的 alias:

alias jcs="codesign -dvvv --entitlements :-"

甚至可以写一个 shell 函数进来:

unproxy() {
    unset http_proxy
    unset https_proxy
    echo "Proxy Unset."
}

这些写进 .profile 文件的东西在登录后,在任意路径下直接使用。把常用命令放进来是一个不错的选择。

通常情况下修改完 .profile 之后我们都需要 source 一下让它生效:

source ~/.profile

那么 source 命令和直接执行它有什么区别呢?感兴趣的读者朋友可以看看这一篇文章:Linux下source命令详解 - 在努力! - CSDN博客

简单来说就是使用 sh filename./filename 来执行脚本的时候,shell 本身会创建一个子 shell 来执行这个脚本。所以在子 shell 里的变量并不会影响到当前的这个父 shell。而 source 执行的时候,并不会创建子 shell 而是直接就在当前 shell 执行了,所以这里面什么 export, alias之类的东西就直接在当前 shell 生效了。

五、iTerm2

macOS 自带的 Terminal.app 已经足够好用,虽然默认是白色底的,字体也比较小,但是你可以在 Preferences 里面修改 Profiles 和字体。在 macOS Mojave 以上你还可以使用 Dark Mode 来让它变成黑色的。

不过还有比他更好用的终端 App — iTerm2

iTerm2 有很多非常实用的 Feature,我最常用的有几个:

  1. 自定义外观和 Profile

    iTerm2 可自定义的外观项比 Terminal 的多,而且还挺酷炫的。最近更新的版本还可以在顶部加入 Status Bar 显示 CPU/Mem 以及当前路径的信息。虽然我不怎么用但是可以看到 iTerm2 的进化速度比 Terminal 快多了。一旦习惯了 iTerm2 的 UI 就回不去了。

  2. 实用的分屏功能

    Terminal 虽然也自带分屏和 Tab,但是 iTerm2 可以通过 cmd+dcmd+w 来新建/关闭当前分屏,通过 cmd+[cmd+] 来左右切换分屏。当我需要多任务操作的时候非常有用。比如我在左边看着本地的目录,右边通过 ssh 登录服务器对着服务器的目录,两边做数据交换。

  3. 随时用全局快捷键呼出的 Hotkey Window

    在 Preferences 里面选择 Keys -> HotKey -> Create a Dedicated Hotkey Window… 之后可以创建一个专门对应全局快捷键的终端窗口。按下自定义快捷键之后就会 slide in。虽然我自己用的不多但这是 iTerm2 挺受欢迎的一个特性。

  4. 实用的小细节

    • 可以按住 cmd 使用鼠标打开链接
    • Tab 顶部会显示当前的任务和状态
    • 分屏的时候会让不活动的屏幕变浅色

iTerm2 还有许多有用的小细节,在日常使用的时候不会觉得有什么了不起,但是当你到别人的机器上用什么都没改过的 Terminal 的时候忽然就发现:我擦,怎么这么难用?这就是好的设计应该有的感觉。

六、快捷键

大部分终端 App 都会支持一些非常实用的快捷键操作。我们无论使用哪一个 App,只要是经常用的 App,经常用的动作,都应该学习使用快捷键。

在终端中我比较常用的几个快捷键有:

Key Action
alt+left 往左跳一个单词
alt+right 往右跳一个单词
ctrl+w 向左删掉一个单词
ctrl+u 删掉一整行
ctrl+l clear 整个终端的输出
cmd+enter iTerm2 的全屏/取消全屏快捷键

不同的终端 App 设置的快捷键可能不一样但都大同小异,完整的 iTerm2 Cheat Sheet 在这里大家可以参考一下: iTerm2 Cheat Sheet - Kapeli

有一个叫做 CheatSheet 的 App 可以长按 ⌘ 来查看当前 App 的所有快捷键,不过体验并不是很好。一般我会选择 Google: App + Cheat Sheet 来获得该 App 的 Cheat Sheet 列表。

比如 Tower 就整理了一份不错的 Xcode Cheat Sheet 在这里: Xcode Cheat Sheet。对于 iOS 开发者来说,每天面对 Xcode 的时间贼多,不掌握点快捷键怎么可以呢?

七、参考资料

相关链接