名校课程推荐 | MIT《CS 实用工具课程》-命令行环境

命令行环境

别名和函数

可以想象,输入一长串包含多个flag或verbose选项的长命令很麻烦。不过,大多数shell支持设置别名。例如,bash中的别名语法如下(注意=符号前后没有空格):

alias alias_name="command_to_alias"

别名有很多便捷属性

# Alias can summarize good default flags 
(别名可以创建常见命令的缩写)
alias ll="ls -lh"

# Save a lot of typing for common commands 
(可以节省很多常规命令的输入)
alias gc="git commit"

# Alias can overwrite existing commands 
(别名可以覆盖现有的命令)
alias mv="mv -i"
alias mkdir="mkdir -p"

# Alias can be composed 
(别名可以组合使用)
alias la="ls -A"
alias lla="la -l"

# To ignore an alias run it prepended with \ 
(在前面加上\忽略某个别名)
\ls
# Or can be disabled using unalias 
(或者禁用别名)
unalias la

但是在多数情况下别名可能会受到限制,特别是当你试图编写带有相同参数的链式命令时。另一种选择是函数,它是别名和自定义shell脚本之间的中点。

下面这个例子是函数创建一个目录并移入该目录。

mcd () {
    mkdir -p $1
    cd $1
}

在默认情况下,别名和函数不会在shell会话中持续生效,为了让别名持续生效,需要将它包含在shell启动脚本文件中,如.bashrc.zshrc。我的建议是将它们分别写入.aliassource中,并从不同的shell配置文件中获取。

Shell和框架

在shell和脚本一节中我们介绍了bash shell,它是目前最通用的shell,大多数系统都把它作为默认shell。但它并不是唯一的选择。

比如,zsh shell是bash的超集,它提供了许多方便的功能:

  • 智能globbing通配,**

  • 行内globbing/通配符扩展

  • 拼写校正

  • 更好的tab补全和选择

  • 路径扩展(cd /u/lo/b 扩展为 /usr/local/bin

很多shell也可以通过框架进行改进,包括一些流行的通用框架,如preztooh-my-zsh,还有一些更精简的框架,它们一般专注于某个特定功能,如zsh语法高亮zsh历史子串查询。其他shell比如fish,默认情况下包含了很多用户友好的功能,包括:

  • 向右对齐

  • 命令语法高亮

  • 历史子串查询

  • 基于手册页的选项补全

  • 更智能的自动补全

  • 提示符主题

在使用这些框架时需要注意,如果这些框架的代码没有合理优化或者代码过多,你的shell性能可能会降低。你随时可以测试其性能或禁用某些不常用的功能来实现速度与功能的平衡。

终端模拟器和终端多路复用

和自定义shell一样,花点时间选择你的终端模拟器及其设置很有必要。有很多终端模拟器可以选择(这里有一个它们之间的比较)。

因为你可能需要花大量时间在终端上,因此研究一下终端的设置很有必要,你可以从以下几方面设置你的终端:

  • 字体选择

  • 彩色主题

  • 快捷键

  • 标签页/面板支持

  • 回退配置

  • 性能(像 Alacritty  这种比较新的终端支持GPU加速)

还要说一下像tmux这类终端复用器tmux允许你基于面板和标签分割出多个终端窗口,这样就可以实现多个shell会话。如果在远程服务器上工作,想让你的shell继续运行而不必担心脱离当前进程(默认情况下,登出时进程会随之终止),tmux会支持分离当前终端对话并在之后重新连接。这样,使用tmux就可以进入和退出复杂的终端部署。和终端模拟器类似,通过编辑~/.tmux.conf文件可以定制自己的tmux

命令行工具

大多数基于UNIX的操作系统默认的命令行工具足以完成你通常需要完成的99%的工作。

在下面几个小节中,我会介绍更方便使用的非常常见的shell操作的替代工具。其中一些工具为命令添加了新的改进功能,而另一些工具则专注于用更好的默认设置提供更简单、更直观的界面。

fasd vs cd

即使改进了路径扩展和标签自动完成功能,我们可能也要反复更改目录。Fasd(或自动跳转)通过追踪最近及最频繁操作的文件夹并执行模糊匹配解决了这个问题。

因此,如果我访问了/home/user/awesome_project/code路径,运行z code,将cd进入该目录。如果我有多个叫做代码的文件夹,我可以通过运行z awe code来消除歧义,这会更接近匹配。与自动跳转不同的是,fasd还提供了一些命令,这些命令不是执行cd,而是扩展频繁操作的及/或最近的文件和/或文件夹。

bat vs cat

尽管cat表现的很好,但bat通过提供语法高亮、分页、行号和git集成改进了cat。

exa/ranger vs ls

ls是一个很好的命令,但有些默认值可能比较烦人,比如以原始字节显示大小。exa提供了更好的默认值。

如果你需要浏览多个文件夹和/或预览多个文件,ranger可能比cdcat更高效,因为它的出色的接口。通过正确的设置,你可以对它进行定制甚至可以在你的终端预览图像

fd vs find

fdfind的一个简单、快速并且用户友好的替代品。find默认值,比如必须使用--name标签(这是你在99%的情况下要做的),使其在日常使用中更容易。它也会识别git,默认情况下会跳过.gitignore.git文件夹中的文件。默认情况下,它也有漂亮的颜色编码。

rg/fzf vs grep

grep是一个非常棒的工具,但是如果您想要同时对多个文件进行grep搜索,有更好的工具可以达到这一目的。ack, ag & rg在你的当前目录中搜索正则表达式模式,同时尊重你的gitignore规则。它们非常相似,但我更喜欢rg,因为它可以快速搜索我的整个主目录。

类似地,你很容易发现自己一遍又一遍地执行CMD | grep PATTERNfsf是一个命令行模糊查找器,它让你能够对几乎任何命令的输出进行交互过滤。

rsync vs cp/scp

虽然mvscp对于大多数场景都很完美,但在复制/移动大量文件、大文件,或者一些数据已经在目的地的情况下,rsync是巨大的进步。rsync将跳过已经传输的文件,使用--partial标签可以回复之前中断的副本。

trash vs rm

rm是需要谨慎使用的命令,因为一旦你用rm删除了某个文件,它就消失了。但是现在的操作系统不会这样做,当你在文件管理器中删除一些东西,他们只是把它移动到垃圾文件夹,然后定期执行清除。

因为垃圾箱的管理方式因操作系统而异,所以没有统一的命令行界面工具。mac操作系统中是回收站,linux系统是回收站命令行界面

mosh vs ssh

ssh是一个非常方便的工具,但是如果连接缓慢,网络延迟会很烦,如果连接中断,你必须要重新连接。mosh是一个方便的工具,它支持漫游、断续连接,并提供智能本地回显等功能。

tldr vs man

大多数情况下,你可以使用man(使用手册)和-h/’-help’标签了解某个命令的功能以及它有哪些选项。但是如果这个手册又长又硬那就让人望而却步了。

tldr命令是社区驱动的一个文档系统,它是简化版的使用手册,只显示常用的几个使用示例,说明该命令的功能和最常见的参数选项。

aunpack vs tar/unzip/unrar

要记住tar的选项相当有难度,那这时你需要一个完全不同的工具,例如.rar文件的unraratool工具包提供了aunpack命令,该命令会找出正确的选项,并总是将提取的存档文件放入一个新文件夹中。

练习

  1. 运行cat .bash_history | sort | uniq -c | sort -rn | head -n 10 (或者zsh中 cat .zhistory | sort | uniq -c | sort -rn | head -n 10),找出最常用的10个命令,并将它们重命名成更短的别名。
  2. 选择一个终端模拟器,并了解如何更改以下属性:
    • 字体选择
    • 配色方案。一个标准方案有多少种颜色?为什么?
    • 保留的历史输出大小
  3. 安装fasd或类似的软件,编写一个名为v的bash/zsh函数,它对传入的参数执行模糊匹配并在你选择的编辑器中打开顶部结果。然后,进行修改,这样如果有多个匹配项,你可以用fzf对它们进行选择。
  4. 由于用fzf执行模糊搜索非常方便,而且shell历史记录很容易出现这种搜索,研究一下如何将fzf绑定到^R。你可以在这里获取一些信息
  5. ack中的--bar选项有什么功能?
客服