你不可或缺的 Bash 别名

厌倦了一遍又一遍地输入相同的长命令吗? 您是否觉得在命令行上工作效率低下? Bash 别名可以带来翻天覆地的变化。
610 位读者喜欢这个。
bash logo on green background

Opensource.com

Bash 别名是一种使用新命令补充或覆盖 Bash 命令的方法。 Bash 别名使用户可以轻松地在 POSIX 终端中自定义他们的体验。它们通常在 $HOME/.bashrc$HOME/bash_aliases 中定义(必须由 $HOME/.bashrc 加载)。

大多数发行版至少会在任何新用户帐户的默认 .bashrc 文件中添加一些流行的别名。 这些是一些简单的别名,用于演示 Bash 别名的语法

alias ls='ls -F'
alias ll='ls -lh'

但并非所有发行版都附带预先填充的别名。 如果手动添加别名,则必须将它们加载到当前的 Bash 会话中

$ source ~/.bashrc

否则,您可以关闭终端并重新打开它,以便它重新加载其配置文件。

通过在 Bash 初始化脚本中定义这些别名,您可以键入 ll 并获得 ls -l 的结果,并且在您键入 ls 时,您会得到,而不是普通的 ls 的输出。

这些别名非常好用,但它们只是冰山一角。 以下是排名前 10 位的 Bash 别名,一旦您尝试使用它们,您就离不开它们了。

首先设置

开始之前,创建一个名为 ~/.bash_aliases 的文件

$ touch ~/.bash_aliases

然后,确保此代码出现在您的 ~/.bashrc 文件中

if [ -e $HOME/.bash_aliases ]; then
    source $HOME/.bash_aliases
fi

如果您想亲自尝试本文中的任何别名,请将它们输入到您的 .bash_aliases 文件中,然后使用 source ~/.bashrc 命令将它们加载到您的 Bash 会话中。

按文件大小排序

如果您从使用 GUI 文件管理器(如 GNOME 中的 Nautilus、MacOS 中的 Finder 或 Windows 中的 Explorer)开始您的计算机生涯,那么您可能习惯于按文件大小对文件列表进行排序。 您也可以在终端中执行此操作,但它并不简洁。

在 GNU 系统上将此别名添加到您的配置中

alias lt='ls --human-readable --size -1 -S --classify'

此别名将 lt 替换为 ls 命令,该命令显示每个项目的大小,然后按大小排序,以单列显示,并带有指示文件类型的符号。 加载您的新别名,然后尝试一下

$ source ~/.bashrc
$ lt
total 344K
140K configure*
 44K aclocal.m4
 36K LICENSE
 32K config.status*
 24K Makefile
 24K Makefile.in
 12K config.log
8.0K README.md
4.0K info.slackermedia.Git-portal.json
4.0K git-portal.spec
4.0K flatpak.path.patch
4.0K Makefile.am*
4.0K dot-gitlab.ci.yml
4.0K configure.ac*
   0 autom4te.cache/
   0 share/
   0 bin/
   0 install-sh@
   0 compile@
   0 missing@
   0 COPYING@

在 MacOS 或 BSD 上,ls 命令没有相同的选项,因此可以使用此别名代替

alias lt='du -sh * | sort -h'

此版本的结果略有不同

$ du -sh * | sort -h
0	compile
0	COPYING
0	install-sh
0	missing
4.0K	configure.ac
4.0K	dot-gitlab.ci.yml
4.0K	flatpak.path.patch
4.0K	git-portal.spec
4.0K	info.slackermedia.Git-portal.json
4.0K	Makefile.am
8.0K	README.md
12K	config.log
16K	bin
24K	Makefile
24K	Makefile.in
32K	config.status
36K	LICENSE
44K	aclocal.m4
60K	share
140K	configure
476K	autom4te.cache

事实上,即使在 Linux 上,该命令也很有用,因为使用 ls 会将目录和符号链接列为大小为 0,这可能不是您实际想要的信息。 由你选择。

感谢 Brad Alexander 的这个别名创意。

仅查看已挂载的驱动器

mount 命令曾经非常简单。 只需一个命令,您就可以获得计算机上所有已挂载文件系统的列表,并且它经常用于概览有哪些驱动器连接到工作站。 看到超过三四个条目曾经令人印象深刻,因为大多数计算机没有那么多 USB 端口,因此结果是可管理的。

现在的计算机有点复杂,并且在 LVM、物理驱动器、网络存储和虚拟文件系统之间,mount 的结果可能难以解析

sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime,seclabel)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
devtmpfs on /dev type devtmpfs (rw,nosuid,seclabel,size=8131024k,nr_inodes=2032756,mode=755)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
[...]
/dev/nvme0n1p2 on /boot type ext4 (rw,relatime,seclabel)
/dev/nvme0n1p1 on /boot/efi type vfat (rw,relatime,fmask=0077,dmask=0077,codepage=437,iocharset=ascii,shortname=winnt,errors=remount-ro)
[...]
gvfsd-fuse on /run/user/100977/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,relatime,user_id=100977,group_id=100977)
/dev/sda1 on /run/media/seth/pocket type ext4 (rw,nosuid,nodev,relatime,seclabel,uhelper=udisks2)
/dev/sdc1 on /run/media/seth/trip type ext4 (rw,nosuid,nodev,relatime,seclabel,uhelper=udisks2)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,relatime)

要解决这个问题,请尝试这样的别名

alias mnt="mount | awk -F' ' '{ printf \"%s\t%s\n\",\$1,\$3; }' | column -t | egrep ^/dev/ | sort"

此别名使用 awk 按列解析 mount 的输出,从而将输出减少到您可能正在寻找的内容(挂载了哪些硬盘驱动器,而不是文件系统)

$ mnt
/dev/mapper/fedora-root  /
/dev/nvme0n1p1           /boot/efi
/dev/nvme0n1p2           /boot
/dev/sda1                /run/media/seth/pocket
/dev/sdc1                /run/media/seth/trip

在 MacOS 上,mount 命令不提供非常详细的输出,因此别名可能有点过头了。 但是,如果您喜欢简洁的报告,请尝试此操作

alias mnt='mount | grep -E ^/dev | column -t'

结果

$ mnt
/dev/disk1s1  on  /                (apfs,  local,  journaled)
/dev/disk1s4  on  /private/var/vm  (apfs,  local,  noexec,     journaled,  noatime,  nobrowse)

在 grep 历史记录中查找命令

有时您会弄清楚如何在终端中做某事,并向自己保证永远不会忘记刚刚学到的东西。 然后一个小时过去了,你完全忘记了你做了什么。

每个人都必须不时地搜索他们的 Bash 历史记录。 如果您确切知道要搜索的内容,则可以使用 Ctrl+R 在您的历史记录中进行反向搜索,但有时您记不起要查找的确切命令。

这是一个使该任务更容易的别名

alias gh='history|grep'

这是一个如何使用它的例子

$ gh bash
482 cat ~/.bashrc | grep _alias
498 emacs ~/.bashrc
530 emacs ~/.bash_aliases
531 source ~/.bashrc

按修改时间排序

每个星期一都会发生这种情况:您上班,坐在电脑前,打开终端,发现您忘记了上周五在做什么。 您需要一个别名来列出最近修改的文件。

您可以使用 ls 命令创建一个别名来帮助您找到您离开的地方

alias left='ls -t -1'

输出很简单,但如果您愿意,可以使用 --long 选项对其进行扩展。 该别名,如上所列,显示如下

$ left
demo.jpeg
demo.xcf
design-proposal.md
rejects.txt
brainstorm.txt
query-letter.xml

计数文件

如果您需要知道目录中有多少文件,解决方案是 UNIX 命令构造中最经典的示例之一:您使用 ls 命令列出文件,使用 -1 选项控制其输出仅为一列,然后将该输出管道传输到 wc(字数统计)命令以计算有多少行单个文件。

这是一个很好的演示,说明 UNIX 哲学如何允许用户使用小型系统组件构建自己的解决方案。 如果您碰巧每天都要执行此操作多次,那么此命令组合也需要大量输入,并且如果不使用 -R 选项,它不适用于目录的目录,这将为输出引入新行并使练习毫无用处。

相反,此别名使该过程变得容易

alias count='find . -type f | wc -l'

此别名计算文件,忽略目录,但 *不* 忽略目录的内容。 如果您有一个包含两个目录的项目文件夹,每个目录包含两个文件,则别名返回四个,因为整个项目中有四个文件。

$ ls
foo   bar
$ count
4

创建一个 Python 虚拟环境

您用 Python 编码吗?

您经常用 Python 编码吗?

如果您这样做,那么您知道创建一个 Python 虚拟环境至少需要 53 次击键。

这太多了 49 个,但这很容易通过两个名为 veva 的新别名来避免

alias ve='python3 -m venv ./venv'
alias va='source ./venv/bin/activate'

运行 ve 会创建一个名为 venv 的新目录,其中包含 Python3 的常用虚拟环境文件系统。 va 别名会在您当前的 shell 中激活环境

$ cd my-project
$ ve 
$ va
(venv) $ 

添加复制进度条

每个人都取笑进度条,因为它们臭名昭著地不准确。 然而,在内心深处,我们似乎都想要它们。 UNIX cp 命令没有进度条,但它确实有一个 -v 选项用于详细模式,这意味着它会将正在复制的每个文件的名称回显到您的终端。 这是一个非常好的技巧,但是当您复制一个大文件并且想要指示还有多少文件尚未传输时,它效果不佳。

pv 命令在复制期间提供进度条,但它不常用作默认应用程序。 另一方面,rsync 命令包含在几乎所有可用 POSIX 系统的默认安装中,并且它被广泛认为是远程和本地复制文件的最明智方法之一。

更好的是,它具有内置的进度条。

alias cpv='rsync -ah --info=progress2'

使用此别名与使用 cp 命令相同

$ cpv bigfile.flac /run/media/seth/audio/
          3.83M 6%  213.15MB/s    0:00:00 (xfr#4, to-chk=0/4)

使用此命令的一个有趣的副作用是,rsync 在没有 cp 否则需要的 -r 标志的情况下复制文件和目录。

保护自己免受文件删除事故

您不应该使用 rm 命令。 rm 手册甚至这样说

警告:如果您使用 'rm' 删除文件,通常可以恢复该文件的内容。 如果您希望更有把握地确保内容真正无法恢复,请考虑使用“shred”。

如果您想删除文件,您应该将文件移动到您的回收站,就像您在使用桌面时所做的那样。

POSIX 使这变得容易,因为回收站是文件系统中一个可访问的实际位置。 该位置可能会更改,具体取决于您的平台:在 FreeDesktop 上,回收站位于 ~/.local/share/Trash,而在 MacOS 上,它位于 ~/.Trash,但无论哪种方式,它只是一个您将文件放入的目录,您希望将文件隐藏起来,直到您准备好永远删除它们。

这个简单的别名提供了一种从终端将文件扔进回收站的方法

alias tcn='mv --force -t ~/.local/share/Trash '

此别名使用一个鲜为人知的 mv 标志,使您可以将要移动的文件作为最终参数提供,而忽略了该文件必须首先列出的通常要求。 现在您可以使用您的新命令将文件和文件夹移动到您的系统回收站

$ ls 
foo  bar
$ tcn foo
$ ls
bar 

现在该文件“消失”了,但直到您在冷汗中意识到您仍然需要它。 此时,您可以从您的系统回收站中恢复该文件; 务必在离开时向 Bash 和 mv 开发人员致谢。

注意:如果您需要一个更强大的 Trash 命令,并具有更好的 FreeDesktop 合规性,请参阅 Trashy

简化您的 Git 工作流程

每个人都有一个独特的工作流程,但无论如何通常都有重复的任务。 如果您定期使用 Git,那么您可能会发现自己经常重复某些序列。 也许您会发现自己回到 master 分支并在一天中一遍又一遍地提取最新的更改,或者也许您会发现自己创建标签然后将它们推送到远程,或者也许完全是其他的事情。

无论您厌倦了输入哪种 Git 咒语,您都可以通过 Bash 别名来减轻一些痛苦。 主要由于其能够将参数传递给 hooks,Git 具有丰富的内省命令集,可以使您免于在 Bash 中执行不可思议的壮举。

例如,虽然您可能很难在 Bash 中找到项目的顶层目录(就 Bash 而言,这是一个完全任意的指定,因为计算机的绝对顶层是根目录),但 Git 知道其顶层,只需一个简单的查询。 如果您学习 Git hooks,您会发现自己能够找到 Bash 一无所知的所有类型的信息,但您可以使用 Bash 别名来利用该信息。

这是一个别名,用于查找 Git 项目的顶层,无论您当前在该项目的哪个位置工作,然后更改目录到该目录,更改到 master 分支,并执行 Git pull

alias startgit='cd `git rev-parse --show-toplevel` && git checkout master && git pull'

这种别名绝不是一种通用的别名,但它演示了一个相对简单的别名如何消除大量费力的导航、命令和等待提示。

一个更简单,可能更通用的别名会将你返回到 Git 项目的顶层。这个别名非常有用,因为当你正在处理一个项目时,该项目或多或少会成为你的“临时主目录”。像回到你实际的家一样,回到“家”应该很简单,这里有一个别名可以做到这一点

alias cg='cd `git rev-parse --show-toplevel`'

现在,无论你深入到目录结构的什么位置,命令 cg 都会将你带到 Git 项目的顶部。

同时更改目录并查看内容

曾经(据称)有一位顶尖科学家提出,我们可以通过利用极客们键入 cd 后跟 ls 所消耗的能量来解决地球上的许多能源问题。

这是一种常见的模式,因为通常当你更改目录时,你会有查看周围环境的冲动或需求。

但是“浏览”计算机的目录树不必是一个启动和停止的过程。

这是一个作弊,因为它根本不是别名,但这是一个探索 Bash 函数的绝佳借口。虽然别名非常适合快速替换,但 Bash 允许你在你的 .bashrc 文件中添加本地函数(或者你加载到 .bashrc 中的单独的函数文件,就像你处理别名文件一样)。

为了保持模块化,创建一个名为 ~/.bash_functions 的新文件,然后让你的 .bashrc 加载它

if [ -e $HOME/.bash_functions ]; then
    source $HOME/.bash_functions
fi

在函数文件中,添加此代码

function cl() {
    DIR="$*";
	# if no DIR given, go home
	if [ $# -lt 1 ]; then 
		DIR=$HOME;
    fi;
    builtin cd "${DIR}" && \
    # use your preferred ls command
	ls -F --color=auto
}

将函数加载到你的 Bash 会话中,然后试用它

$ source ~/.bash_functions
$ cl Documents
foo bar baz
$ pwd
/home/seth/Documents
$ cl ..
Desktop  Documents  Downloads
[...]
$ pwd
/home/seth

函数比别名灵活得多,但这种灵活性也带来了责任,你需要确保你的代码有意义并且能达到你期望的效果。别名旨在简单,因此请保持它们的简单和有用。对于 Bash 行为的重大修改,请使用函数或自定义 shell 脚本,并将它们保存到 PATH 中的某个位置。

顺便说一句,确实有一些巧妙的技巧可以将 cdls 序列实现为别名,所以如果你足够耐心,即使使用简陋的别名,天空也是极限。

开始使用别名和函数

自定义你的环境是让 Linux 变得有趣的原因,而提高你的效率是让 Linux 改变生活的原因。从简单的别名开始,进阶到函数,并在评论中发布你必备的别名!

接下来要读什么
标签
Seth Kenlon
Seth Kenlon 是一位 UNIX 极客、自由文化倡导者、独立多媒体艺术家和 D&D 爱好者。他曾在电影和计算行业工作,通常同时从事这两项工作。

28 条评论

很棒的文章。感谢这次回顾。

另一个日常程序
alias aptuu='sudo apt update && apt list --upgradable && sudo apt upgrade'

这是一个很棒的别名。我忘记了需要告诉 apt 进行更新(因为相反,需要告诉 dnf 何时不要检查更新,使用 ``--cacheonly``,并且 slackpkg 很少需要更新,除非我在 Changelog 中看到新条目),所以这是一个很棒的别名,谢谢!

回复 作者: Stanowczo (未验证)

为你简化了一些 bash/awk
function mnt() { mount | awk '$1 ~ /\/dev/ { print $1,$3; }' | column -t | sort ; }
alias left='ls -t -1 -r'

由于你显式地调用 bash,请使用 [[ 而不是 [,例如
if [[ -e $HOME/.bash_functions ]]; then

还要用双引号括起来所有变量,并使用 $() 而不是反引号。

或者一般来说,在你编写的每个脚本/函数/命令上使用 ShellCheck。

很好的建议,谢谢。我很惊讶自己没有用双引号括起来我的变量!

我还不一定赞同使用 $() 代替反引号的想法。我也使用 tcsh,虽然 Bash 别名对那个 shell 没有用处,但是使用反引号的习惯对 tcsh 仍然有用(因为它仍然将 $() 解释为尝试调用变量),所以我可能会继续默认使用反引号来保持我自己的内部一致性。

回复 作者: Marcin Pohl (未验证)

我发现我需要对别名的数量保持保守,这样我才不会把自己搞糊涂。
我有时需要使用的一个非常重要的命令是 'alias'(单独使用)——它的作用是列出当前 bash 会话中所有活动的别名。
你还可以创建一个临时别名,例如输入
alias ll='ls -lt'
在当前 bash 会话中,它将仅在该会话期间继续工作(类似于进行试驾)。
同样重要的是要注意语法是严格的。例如,在上面,你不能在 ll 和等号之间或等号和命令之间有空格。

同样值得一提的是,你不必将所有你能想到的标志都塞进你的别名中。你可以创建一个更受限制的别名,并且仍然可以根据需要添加其他标志。例如,对于我的 ll 别名,我可以在 bash 会话中运行
ll -h
这将与
ls -lth

啊,很好的建议。应该提到这一点。再次,我想我会将这个建议转发给即将发布的别名文章的作者,以确保它被提及!

回复 作者: Greg P

我非常喜欢的一个函数是 diff 一个文件及其备份的函数。
它大致是这样的

#!/usr/bin/env bash
file="${1:?未给定文件}"

if [[ ! -e "$file" || ! -e "$file"~ ]]; then
echo "文件不存在或没有备份" 1>&2
exit 1
fi

diff --color=always "$file"{~,} | less -r

我可能把 if 搞错了,但你知道我的意思。我正在用手机输入这些,不在家。
干杯

这非常巧妙!我喜欢它。

我选择的备份工具(rdiff-backup)可以很好地处理这些类型的比较,所以我通常对我的备份文件充满信心。也就是说,总会有特殊情况,这种函数是解决这些问题的绝佳方案。谢谢!

回复 作者: ACG (未验证)

哦,我可能没有说清楚,但我所说的备份是指你的文本编辑器在保存你正在编辑的文件的副本时,会在文件名后附加一个波浪线。每次我遇到 xyz.txt 和 xyz.txt~ 时,我都会想知道这两者之间有什么区别。过了一段时间,打出整个东西变得很无聊,所以我写了这个小脚本。

回复 作者: sethkenlon

更清楚了,现在我肯定会使用它。我自己也多次遇到过这个问题。

回复 作者: ACG (未验证)

你的 mnt 别名(alias mnt='mount | awk -F' ' '{ printf "%s\t%s\n",$1,$3; }' | column -t | egrep ^/dev/ | sort')无法按原样工作,因为你需要为别名定义本身添加第三个引号字符 :-)

Marcin Pohl 通过使用函数给你提供了一个很好的解决方案,但是如果你坚持将其作为别名,你只需要像这样引用一些 "'s 和 $'s 才能使其工作

alias mnt="mount | awk -F' ' '{ printf \"%s\t%s\n\",\$1,\$3; }' | column -t | egrep ^/dev/ | sort"

分享和享受!

感谢你指出这一点。我已经更正了文章中的内容。

由于这篇文章专门讨论 bash 别名,我将它保留为一个别名(它确实是我在自己的 .bashrc 中使用的,除了将其输入到 CMS 中之外,我没有任何问题!),而不是一个函数。

我认为关于 Bash 函数还有很多要说的,所以也许将来会有一篇关于该主题的文章。

回复:,作者:Michael Davies (未验证)

我经常需要打开一个新的终端窗口,并回到我之前所在的位置。我可以输入 xterm,或者 gnome-terminal (太长了),但这个方法不需要你在运行后续命令时位于提示符下,因为你可以从*新的*提示符下运行它。而且它适用于 tmux 或 screen。

它们分别代表 "pwd remember" (记住当前目录)和 "cd [to] remembered [place]" (切换到记住的位置)。

alias pwdr='pwd > ~/.pwdremember'
alias cdr='cd $(cat ~/.pwdremember)'

我喜欢这个!我可能会尝试一下,看看能不能把它变成我自己的习惯。

回复:,作者:Greg Bell (未验证)

如果你把你的别名命名为与命令相同,而且你希望在某些时候使用“正常的” ls,你可以使用反斜杠,例如 \ls

好技巧。我以为我已经把它写进这篇文章里了,但我肯定是在另一篇文章里提到过,因为我没在这里看到。

另一种方法是直接使用命令的绝对路径。

回复:,作者:Greg Bell (未验证)

嗨,Seth,
谢谢你的这些有用的“快捷方式”。
如果可以的话,我建议一个更简单的 mnt 版本。

mount | grep ^/dev | gawk '{ print $1,$3}' | column -t | sort

我的一些“不能没有的”东西是基于正则表达式的。

Decomment 删除整行的注释和空白行。 例如,当查看一个“默认”的 /etc/httpd/whatever.conf 文件,其中有无数行时,

alias decomment='egrep -v "^[[:space:]]*((#|;|//).*)?$" '

会显示文件中只有四行实际上 *做* 了任何事情,而无数减去四行是注释。 我一直将此用于配置文件、Python(和其他语言)代码,以及天知道其他什么地方。

然后是 unprintables 和 expletives,它们非常相似

alias unprintable='grep --color="auto" -P -n "[\x00-\x1E]"'
alias expletives='grep --color="auto" -P -n "[^\x00-\x7E]" '

第一个显示文件中哪些行(带有行号)包含控制字符,第二个显示文件中哪些行包含任何“高于”RUBOUT 的字符,呃,请原谅,我的意思是高于 ASCII 127。 (我感觉老了。) ;-) 当例如,有人给你一个他们用 LibreOffice 编辑或创建的程序时,并且糟糕...一半的引号字符串都有“真正的”花式开头和结尾引号,而不是 ASCII 0x22 “直”引号分隔符时,这很有用……但实际上你想保留一些花式引号,因此“一举全部摧毁”的方法行不通。

你的 `cl` 函数可以简化,因为没有参数的 `cd` 已经会跳转到 home 目录。

```
function cl() {
cd "$@" && \
ls -F --color=auto
}
```

我 .bash_aliases 文件中的第一个别名始终是

alias realias='vim ~/.bash_aliases; source ~/.bash_aliases'

将 vim 替换为你喜欢的编辑器或 $VISUAL

感谢这篇文章! 我创建了一个 Github 仓库 - https://github.com/bhuvana-guna/awesome-bash-shortcuts
目的是创建一个扩展的别名/函数列表,用于各种程序。 由于我是终端和 Linux 的新手,请贡献这些和其他超级棒的实用程序,并帮助其他人轻松访问它们。

Creative Commons License此作品已根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.