命令行(CLI)

简单地说,命令行(Command-line interface, CLI)就是通过命令让电脑执行操作的用户界面,而图形用户界面(Graphical user interface, GUI)则是人们更熟悉的以图形方式显示、通过鼠标或触摸屏操作的用户界面。没有人能够否认GUI在个人电脑以及移动设备上的重要地位,但是,命令行仍然有一些特性,GUI也无法取代。

为什么学习命令行

GUI的最大优势是所见即所得——WYSIWYG(What you see is what you get),不像命令行,如果不知道相关的命令,就什么都做不了,在GUI上你可以寻找需要的功能菜单或图标,只要点一点就可以操作;而因此带来的缺点便是所见即全部所得——WYSIAYG(What you see is all you get),你要做一些操作,必须在界面上点(当然快捷键可以代替一部分点击操作),有时候这些操作可能要重复多次,或者分布在很多个不同的界面(有时候在这些界面间切换还需要一定的时间)。

在某种意义上,命令行就是用电脑能够理解的语言把你想问或者想做的事告诉电脑,它就会回答或者去做。命令行是接近于 所想即所得 的用户界面,只要你的所想能够用人和电脑都能理解的语言表达出来(“语言的边界即思想的边界”,不确定这是维特根斯坦还是柏拉图的意思了……)。不仅仅是操作系统的命令行,像Python等编程语言的交互式执行界面、乃至Siri、AI聊天机器人,都是特殊形式的命令行。

微信的某句理念是“聊天即服务”。更宏观一点地说,对话,似乎更可能成为面向未来的交互界面。命令行作为对话的初级形式,从电脑的上古时代会延伸到未来,大约正因为其中蕴含了交互的核心模式。

这里只说操作系统的命令行,它的优势是:

  • 执行某些操作比GUI更快,更容易重复操作、批量操作、自动化。
  • 可以执行某些GUI无法进行的操作。
  • 更容易把各种工具自由组合。
  • 命令行工具比GUI工具更容易开发,因此不仅自己编程写工具相对更容易,而且在开源世界中找需要的工具也会有更多选择。

命令行的学习提纲

准备工作

现如今个人电脑上的命令行已不再像上古时代的终端或DOS系统那样,只有一个黑白的文字界面,而是作为操作系统图形界面的一部分,一个和电脑对话的聊天窗口。在Mac、Linux等类Unix系统上,它叫Terminal(仍然保留了上古时代的“终端”这个名字),在Windows系统上,它叫命令提示符或Power Shell或其它第三方Shell工具。下文主要以Mac为例。

命令行有几种常见别名:Command-line, Terminal, Shell, Console。

初学的话,系统自带的Terminal已经可以满足需要,而且包括许多贴心(必备)的功能,如半透明窗口,不是为了炫酷,而是在操作命令行时方便看到后面窗口的内容。

如果经常使用的话,iTerm2已被公认是Mac上最好的终端工具,它的功能是Terminal的超集。

基本操作

这篇文章是一篇不错的入门引导:How to Use Terminal: The Basics

提示

  • 不需要像记单词一样记命令,而是常用的命令自然会记住(乃至形成肌肉记忆),不常用的命令需要时看帮助、上网搜都是分分钟的小事。
  • 命令通常都是相关单词或短语的缩写。而且你也许会慢慢感受到设计者为了让命令更短而无所不用其极,这其中包含了几十年的历史筛选和不计其数的程序员的思考结晶。

常用基本命令

命令 含义 说明
pwd print working directory 显示当前路径
ls list / looks 列出当前路径的内容
cd change directory 切换到指定文件夹路径
mkdir make directory 创建文件夹
rmdir remove directory 删除空文件夹(比rm -rf相对安全)
mv move 移动文件或文件夹
cp copy 复制文件或文件夹
rm remove 删除文件或文件夹(不是放到Trash,而是直接删除。需要特别注意rm -rf,r表示递归删除子文件夹,f表示强制删除不提示)
cat/head/tail - 显示文件内容/显示文件开头/显示文件结尾
touch - “触摸”一下某个文件(改变文件的访问或修改时间,也可以用于创建一个空文件)
chmod change mode 修改文件的模式
more/less - 当命令输出内容过多时,用于控制输出内容的显示
grep global regular expression print 根据条件过滤命令输出内容
man manual 查看一个命令的帮助文档
alias - 设置命令别名(用于把较长的命令设置为自己想要的更短或更容易记的别名)

需要了解的基础知识

路径(path)

路径是电脑上某个文件夹或文件的唯一标识。和图形界面是一致的。文件夹的路径有时也称作目录。

  • ~:表示当前用户的家目录(home directory)。通常也是打开Terminal时的默认路径。如:cd ~, ls ~
  • 相对路径:基于当前路径(pwd)的相对路径。
    • .:当前路径。通常可省略,如cd Downloadscd ./Downloads等价。有时候必需,如移动文件到当前路径是mv ~/Downloads/example.txt ./,执行当前路径的可执行脚本是./example.py等。
    • ..:上层路径。如:cd .., ls ..
  • 绝对路径:从根路径(root directory, 即/)开始指定的路径。如:ls //Users/your_name是家目录的绝对路径,~是其快捷方式。

相对路径和绝对路径的概念在制作网站时也很重要。

上网时在浏览器指定的URL也可以理解为:用浏览器打开域名指定的那台电脑(服务器)上绝对路径指定的那个文件。

管道(pipe)

命令行的优势之一就是可以通过管道灵活组合使用。管道操作符是|,一根管子的形状,其作用是:把前一个命令的输出作为后一个命令的输入。

示例:

  • ls | nl:列出当前路径的内容,然后在前面添加序号。
  • ls | wc -l:列出当前路径的内容,然后计算行数(即当前路径有多少文件和文件夹)。
  • cat file.txt | grep hello | wc -l:计算文件file.txt中包含”hello”的行有多少。

还有几个和管道类似的操作符:

  • >:把命令输出写到某个文件。如:history > history-log.txt
  • <:从某个文件读取内容作为命令输入。
  • &&:当前一个命令执行成功时执行后一个命令。
  • ||:当前一个命令执行失败时执行后一个命令。
命令行参数(parameters)

大部分命令都可以通过参数控制其执行的效果。同样,参数不需要专门记,常用的自然会记住,不常用的可以查看帮助或上网搜索。

而且命令的参数有一些惯常的约定(也是在长久的历史中形成的),但并不绝对:

  • --help通常是显示该命令的帮助。如:ls --help,这和man ls是查看命令如何使用的最快方式。
  • -a通常表示all。如:ls -a
  • -f通常表示force,强制执行操作。
  • -R通常表示recursive,递归执行。如:ls -R

有用的工具

  • Homebrew被称为Mac上不可或缺的包管理工具,用来安装、升级、卸载第三方命令行工具。
  • Homebrew Cask用来以Homebrew的方式安装管理GUI软件。Mac上安装软件已经非常简便:打开网页、下载软件包、解压、拖到程序目录、删除软件包;而人们总是追求更简便,现在只需要一句话,如:brew cask install google-chrome

  • wget/curl可能也是对非程序员有用的工具。比如自动下载某个网站的一批内容、自动保存我的豆瓣广播/收藏的第1-N页,等等。
  • 文本编辑器。当使用命令行(或者开始学编程)时,会经常需要与纯文本打交道,除了像PyCharm(对Python学习者来说)这样的IDE,一款顺手的文本编辑器也非常必要。Sublime Text是目前非常流行、功能强大、容易上手的一个候选(安装:brew cask install sublime-text);像Vim/Emacs这两个传奇编辑器,学习曲线陡峭,功能或许更强大,但若无特别偏爱,从学习的投入产出比来说并不推荐。

进阶知识

以下各项,对非程序员来说可能并非必要,请自行判断投入产出比。

  • zsh & oh-my-zsh:更强大的命令行解释器及插件。
  • shell scripting:把一组命令组合成批处理脚本(一个新命令),还可以包含命令行参数、if判断、循环、函数等。
  • find & xargs:查找文件和批量执行操作的两个命令。
  • grep, sed, awk:一组基于正则表达式的文本处理命令。
  • git:参看下节。

第一部分篇幅最长。因为对于习惯了GUI的用户,命令行初看似乎令人望而却步。而命令行却堪称是互联网世界的一把钥匙,掌握之后,更广阔的世界便会渐渐展开。

Git & Github & GitBook

Git是目前最流行的版本控制工具。Github是目前最活跃的开源软件平台。

版本控制,简单地说就是管理你的一组文件的每一个版本。这对于编程(写代码)来说是必需的。而如果你用txt/markdown/pandoc来写文章、写博客、写小说、写论文的话,版本控制也会很有帮助,可以查看、比较、恢复你提交过的每一个版本的更改。如果用Pages/Word来写文章当然也可以进行版本控制,但处理二进制文件不是版本控制工具的优势,如比较更改的操作可能就无法进行,同时也会更占用硬盘空间。

学习Git和Github,只看Pro Git这一本书就够了,对非程序员来说甚至只需要看其中的1、2、6章。Git和Github也都提供了GUI的操作工具,但,如上节所述,命令行方式在多数情况下更强大也更便利。

如果熟悉Git和Markdown,用GitBook写书或合作写书会是一种非常便利的方式。

有博客提到学术型 github 畅想。学术研究与软件开发有相似之处,如都需要知识管理、沟通协作、发布成果;但也有较大的区别:学术研究有独立的评价体系,对保密和原创性的要求更高。所以,Github在多大程度上适合作为学术协作平台,仍然需要实践验证。但至少目前,计算机科学、数据分析、实验与计算等与编程相关的研究项目,已经大量出现在Github上。

另外,如果想把IT类工作作为毕业后求职目标(或退路)的话,从现在开始使用Git和Github、参与Github上感兴趣的开源项目,会是一笔非常有帮助的实践。

博客(Blog)或个人网站

博客是互联网时代一个非常有用的整理学习成果、分享交流、持续创作的工具,前人之述备矣。而博客或个人网站也是一个呈现个人履历(CV, Curriculum Vitae)和作品集(Portfolio)的平台。务虚地说,这会是一个人上网多年后积累的可观成果;务实地说,这对找工作或找合作伙伴或出书很有帮助。

国内缺少一个像Blogspot这样主流而可靠的博客托管平台。目前的主流方式是用Jekyll或Hugo这样的网站生成工具、托管在Github Pages,有域名的再绑定自己的域名。买域名+VPS完全自主建站,投入较高,可控性更强。

Google

Google是目前互联网上最好的搜索引擎和最重要的学习工具,没有之一。

比如这篇文章中提到的每一种工具,想知道是什么(What)或怎么用(How),Google一下可能是最快最有效的求解方式。

所以,如何访问Google,如何使用引号、减号、site/inurl关键词进行高级搜索,如何提炼问题然后利用Google寻找答案,也是重要的IT技能。