随着你在命令行上的操作越来越多,你会发现你使用的大部分命令只是可用命令的一个非常小的子集。大多数任务是习惯性的,你可能每天都以相同的方式运行这些任务。
虽然许多常见命令实用程序的制造者已经尝试通过使用缩短的名称(想想每天通过输入"ls"而不是"list"和"cd"而不是"change-directory"来节省多少按键),来消除多余的输入,但这并不是普遍的。此外,许多人每次运行命令时总是启用相同的几个选项。
幸运的是,bash允许我们通过别名和shell函数来创建自己的快捷方式和时间节省器。在本指南中,我们将讨论如何利用这些功能,并为您提供一些有用的示例,以帮助您朝着正确的方向开始。
在bash中声明别名非常简单。它非常容易,你现在就应该尝试一下。
您可以通过简单地在命令行中输入以下内容来声明在整个shell会话期间持续存在的别名。语法如下:
alias 别名="要运行的命令"
请注意,相邻元素和等号之间没有空格。这是不可选的。这里的空格会破坏命令。
现在让我们创建一个常见的bash别名。许多人经常使用的一个成语命令短语是 ls -lha
或 ls -lhA
(第二个省略了当前目录和父目录的列表)。我们可以创建一个名为 ll
的快捷方式,可以通过以下方式调用:
alias ll="ls -lhA"
现在,我们可以输入 ll
,就会得到当前目录的列表,以长格式显示,包括隐藏目录:
ll
-rw-r--r-- 1 root root 3.0K Mar 20 18:03 .bash_history
-rw-r--r-- 1 root root 3.1K Apr 19 2012 .bashrc
drwx------ 2 root root 4.0K Oct 24 14:45 .cache
drwx------ 2 root root 4.0K Mar 20 18:00 .gnupg
-rw-r--r-- 1 root root 0 Oct 24 17:03 .mysql_history
-rw-r--r-- 1 root root 140 Apr 19 2012 .profile
drwx------ 2 root root 4.0K Oct 24 14:21 .ssh
-rw------- 1 root root 3.5K Mar 20 17:24 .viminfo
如果要取消别名,只需使用 unalias
命令:
unalias ll
别名现在已被移除。
您可以通过不带任何参数传递 alias
命令来列出所有配置的别名:
alias
要临时绕过别名(比如我们将 ls
别名为 ls -a
),我们可以输入:
\ls
这将调用我们路径中找到的正常命令,而不使用别名版本。
假设您没有取消它,ll
别名将在当前shell会话期间始终可用,但当您打开新的终端窗口时,它将不可用。
要使其持久化,我们需要将其添加到在shell会话开始时读取的各种文件之一。常见选择是 ~/.bashrc
和 ~/.bash_profile
。我们只需要打开文件并在那里添加别名:
nano ~/.bashrc
在底部或任何您喜欢的地方,添加您在命令行中添加的别名。随时添加一个注释,声明一个专门用于bash别名的整个部分:
#########
# 别名
#########
alias ll="ls -lhA"
这个别名或其变体实际上可能已经在您的文件中。许多发行版都附带了一组标准的bash配置文件,其中包含一些有用的别名。
保存并关闭文件。您添加的任何别名将在下次启动新的shell会话时可用。要将您在文件中做出的任何更改读入当前会话,只需告诉bash现在重新读取文件:
source ~/.bashrc
现在您知道如何创建自己的别名了,让我们谈谈一些可能对您有用的常见别名。这些可以在网上找到,有些也可能包含在您发行版的默认bash配置中。
许多最简单的Linux命令在应用一些格式和选项时更有帮助。
我们上面讨论了一个 ls
示例,但还有许多其他您可能会发现的。
通过默认显示为列和带有文件类型指示符(以"/"结尾的目录等),使 ls
更易于使用:
alias ls="ls -CF"
我们还可以预期一些拼写错误,以便调用正确的命令:
alias sl="ls"
让我们还创建一个别名,将我们的输出管道到 less
,以便查看长格式的大型目录列表:
alias lsl="ls -lhFA | less"
我们也可以远离 ls
,尝试一些对 cd
有帮助的命令。
这个命令将切换到父目录,即使您忘记了空格:
alias cd..="cd .."
您还可以通过为 ..
创建别名来完全省略 cd
部分:
alias ..="cd .."
我们可以通过设置这个别名轻松地在当前目录中找到文件:
alias fhere="find . -name "
我们可以为一些监控和系统统计命令设置别名,因为每次调用时都使用相同的选项,所以最好设置一些别名。
以下命令将以人类可读的单位列出磁盘使用情况,包括文件系统类型,并在底部打印总计:
alias df="df -Tha --total"
我们也可以为我们首选的 du
输出添加一个别名:
alias du="du -ach | sort -h"
让我们继续朝着同样的方向,使我们的 free
输出更加人性化:
alias free="free -mt"
我们可以对进程表进行很多操作。让我们首先设置一个默认输出:
alias ps="ps auxf"
我们可以创建一个别名,用于在我们的进程中搜索我们将传递的参数:
alias psg="ps aux | grep -v grep | grep -i -e VSZ -e"
现在,当我们使用进程名称作为参数调用它时,我们将获得一个简洁的输出:
psg bash
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
1001 5227 0.0 0.0 26320 3376 pts/0 Ss 16:29 0:00 bash
我们经常使用 mkdir
命令的一个常见选项是 -p
标志,以创建必要的父目录。我们可以将其设置为默认值:
alias mkdir="mkdir -p"
我们可能还想在此基础上添加一个 -v
标志,以便在每次目录创建时告知我们,这有助于快速识别是否由于拼写错误导致了意外的目录分支:
alias mkdir="mkdir -pv"
在使用 wget
从互联网下载文件时,几乎在所有情况下,您都会希望传递 -c
标志,以便在出现问题时继续下载。我们可以通过以下方式设置:
alias wget="wget -c"
我们可以像使用 history
命令的输出一样轻松地搜索我们的历史记录。这有时比使用 CTRL-R 进行反向搜索更有用,因为它会给您命令编号,以便在之后进行更复杂的调用:
alias histg="history | grep"
我有一些系统工具,我更喜欢从标准版本升级到更复杂的工具。这些只有在下载了所需的实用程序后才能使用,但它们非常有帮助。请记住,这可能会影响您的其他别名。
以下命令将用增强版本取代传统的 top
命令,该版本更加易于阅读,并且可以进行排序、搜索和滚动而无需复杂操作:
alias top="htop"
类似地,ncdu
命令可以下载,它以交互式的 ncurses 显示形式呈现文件和目录大小,您可以浏览并执行简单的文件操作:
alias du="ncdu"
还有一个名为 pydf
的 df
的升级实用程序。它提供了彩色输出和基于文本的使用情况条形图。如果有的话,我们可以默认使用此实用程序:
alias df="pydf"
您是否曾经需要在命令行中获取您在 NAT 路由器后的公共 IP 地址?类似这样的命令可能会很有用:
alias myip="curl http://ipecho.net/plain; echo"
出于自己的目的,我喜欢优化我上传到文章中的图像,使其宽度不超过 690px,因此我使用 ImageMagick 包(如果尚未安装,请执行 sudo apt-get install imagemagick
)其中包含一个名为 mogrify
的命令来实现这一点。我在我的 ~/.bashrc
文件中有这个命令:
alias webify="mogrify -resize 690\> *.png"
这将调整当前目录中所有的 PNG 图像,只有当它们的宽度超过 690px 时才会调整。
如果我需要将它们上传到服务器,我可以使用 sftp
连接并自动切换到特定目录:
alias upload="sftp [email protected]:/path/to/upload/directory"
尽管别名快速且易于实现,但它们在范围上相当有限。您会发现,在尝试将命令链接在一起时,很难很好地访问运行时给定的参数,等等。有时别名也可能相当慢,因为它们是在所有函数之后读取的。
别名的替代方案是更健壮的,并且可以帮助您弥合别名和完整 shell 脚本之间的差距。这些被称为 shell 函数。它们几乎与别名以相同的方式工作,但更加程序化,并以标准方式接受输入。
我们不会在这里详细介绍,因为它们可以在许多复杂情况下使用,而且 bash 是一种完整的脚本语言,但我们将介绍一些基本示例。
首先,有两种声明 bash 语法的基本方法。第一种使用 function
命令,看起来像这样:
function function_name {
command1
command2
}
另一种语法使用一组括号,更像是 “C” 风格:
function_name () {
command1
command2
}
我们可以将第二种形式压缩成一行,并用分号分隔命令。最后一个命令后必须有一个分号:
function_name () { command1; command2; }
让我们首先演示一个非常有用的 bash 函数。这个函数将创建一个目录,然后立即进入该目录。这通常是我们创建新目录时所采取的确切顺序:
mcd () {
mkdir -p $1
cd $1
}
现在,当我们使用此函数而不是常规的 mkdir
命令时,将自动在创建后切换到该目录:
mcd test
pwd
/home/demouser/test
您会经常看到的一个很酷的函数是 extract
函数。它结合了许多实用程序,允许您解压几乎任何压缩文件格式。有许多变体,但以下来自这里:
function extract {
if [ -z "$1" ]; then
# 如果没有给出参数,则显示用法
echo "Usage: extract ."
echo " extract [path/file_name_2.ext] [path/file_name_3.ext]"
return 1
else
for n in $@
do
if [ -f "$n" ] ; then
case "${n%,}" in
*.tar.bz2|*.tar.gz|*.tar.xz|*.tbz2|*.tgz|*.txz|*.tar)
tar xvf "$n" ;;
*.lzma) unlzma ./"$n" ;;
*.bz2) bunzip2 ./"$n" ;;
*.rar) unrar x -ad ./"$n" ;;
*.gz) gunzip ./"$n" ;;
*.zip) unzip ./"$n" ;;
*.z) uncompress ./"$n" ;;
*.7z|*.arj|*.cab|*.chm|*.deb|*.dmg|*.iso|*.lzh|*.msi|*.rpm|*.udf|*.wim|*.xar)
7z x ./"$n" ;;
*.xz) unxz ./"$n" ;;
*.exe) cabextract ./"$n" ;;
*)
echo "extract: '$n' - unknown archive method"
return 1
;;
esac
else
echo "'$n' - file does not exist"
return 1
fi
done
fi
}
此函数获取第一个参数,并根据所使用的文件扩展名调用适当的实用程序程序。
希望本指南能够给您一些灵感,帮助您创建自己的别名和 bash 函数。广泛使用这些功能可以帮助您在 shell 中更加愉快、更少复杂地工作。
请记住要谨慎地重新定义具有潜在破坏性行为的现有命令。甚至将命令别名化为更安全的变体(例如,在递归删除之前始终要求确认)也可能在您依赖它的系统上第一次没有这个别名时给您带来麻烦。
要找到适合创建别名的候选命令,可以搜索您的历史记录以查找您最常用的命令。以下是一个一行命令,可以让我们看到我们最常用的命令:
history | awk '{CMD[$2]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl | head -n10