不可或缺的Bash別名
厭倦了一遍又一遍地輸入相同的長命令?你覺得在命令行上工作效率低嗎?Bash 別名可以為你創造一個與眾不同的世界。
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 的普通輸出。
那些別名很棒,但它們只是淺嘗輒止。以下是十大 Bash 別名,一旦你試過它們,你會發現再也不能離開它們。
首先設置
在開始之前,創建一個名為 ~/.bash_aliases 的文件:
$ touch ~/.bash_aliases
然后,確認這些代碼出現在你的 ~/.bashrc 文件當中:
if [ -e $HOME/.bash_aliases ]; thensource $HOME/.bash_aliasesfi
如果你想親自嘗試本文中的任何別名,請將它們輸入到 .bash_aliases 文件當中,然后使用 source ~/.bashrc 命令將它們加載到當前 Bash 會話中。
按文件大小排序
如果你一開始使用過 GNOME 中的 Nautilus、MacOS 中的 Finder 或 Windows 中的資源管理器等 GUI 文件管理器,那么你很可能習慣了按文件大小排序文件列表。你也可以在終端上做到這一點,但這條命令不是很簡潔。
將此別名添加到 GNU 系統上的配置中:
alias lt='ls --human-readable --size -1 -S --classify'
此別名將 lt 替換為 ls 命令,該命令在單個列中顯示每個項目的大小,然后按大小對其進行排序,并使用符號表示文件類型。加載新別名,然后試一下:
$ source ~/.bashrc$ lttotal 344K140K configure*44K aclocal.m436K LICENSE32K config.status*24K Makefile24K Makefile.in12K config.log8.0K README.md4.0K info.slackermedia.Git-portal.json4.0K git-portal.spec4.0K flatpak.path.patch4.0K Makefile.am*4.0K dot-gitlab.ci.yml4.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 -h0 compile0 COPYING0 install-sh0 missing4.0K configure.ac4.0K dot-gitlab.ci.yml4.0K flatpak.path.patch4.0K git-portal.spec4.0K info.slackermedia.Git-portal.json4.0K Makefile.am8.0K README.md12K config.log16K bin24K Makefile24K Makefile.in32K config.status36K LICENSE44K aclocal.m460K share140K configure476K 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 bash482 cat ~/.bashrc | grep _alias498 emacs ~/.bashrc530 emacs ~/.bash_aliases531 source ~/.bashrc
按修改時間排序
每個星期一都會這樣:你坐在你的電腦前開始工作,你打開一個終端,你發現你已經忘記了上周五你在做什么。你需要的是列出最近修改的文件的別名。
你可以使用 ls 命令創建別名,以幫助你找到上次離開的位置:
alias left='ls -t -1'
輸出很簡單,但如果你愿意,可以使用 --long 選項擴展它。這個別名列出的顯示如下:
$ leftdemo.jpegdemo.xcfdesign-proposal.mdrejects.txtbrainstorm.txtquery-letter.xml
文件計數
如果你需要知道目錄中有多少文件,那么該解決方案是 UNIX 命令構造的最典型示例之一:使用 ls 命令列出文件,用-1 選項將其輸出控制為只有一列,然后輸出到 wc(單詞計數)命令的管道,以計算有多少行。
這是 UNIX 理念如何允許用戶使用小型的系統組件構建自己的解決方案的精彩演示。如果你碰巧每天都要做幾次,這個命令組合也要輸入很多字母,如果沒有使用 -R 選項,它就不能用于目錄,這會為輸出引入新行并導致無用的結果。
而這個別名使這個過程變得簡單:
alias count='find . -type f | wc -l'
這個別名會計算文件,忽略目錄,但不會忽略目錄的內容。如果你有一個包含兩個目錄的項目文件夾,每個目錄包含兩個文件,則該別名將返回 4,因為整個項目中有 4 個文件。
$ lsfoo bar$ count4
創建 Python 虛擬環境
你用 Python 編程嗎?
你用 Python 編寫了很多程序嗎?
如果是這樣,那么你就知道創建 Python 虛擬環境至少需要 53 次擊鍵。
這個數字里有 49 次是多余的,它很容易被兩個名為 ve 和 va 的新別名所解決:
alias ve='python3 -m venv ./venv'alias va='source ./venv/bin/activate'
運行 ve 會創建一個名為 venv 的新目錄,其中包含 Python 3 的常用虛擬環境文件系統。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 無需 -r 標志就可以復制文件和目錄,而 cp 則需要。
避免意外刪除
你不應該使用 rm 命令。rm 手冊甚至這樣說:
警告:如果使用
rm刪除文件,通常可以恢復該文件的內容。如果你想要更加確保內容真正無法恢復,請考慮使用shred。
如果要刪除文件,則應將文件移動到“廢紙簍”,就像使用桌面時一樣。
POSIX 使這很簡單,因為垃圾桶是文件系統中可訪問的一個實際位置。該位置可能會發生變化,具體取決于你的平臺:在 FreeDesktop 上,“垃圾桶”位于 ~/.local/share/Trash,而在 MacOS 上則是 ~/.Trash,但無論如何,它只是一個目錄,你可以將文件藏在那個看不見的地方,直到你準備永久刪除它們為止。
這個簡單的別名提供了一種從終端將文件扔進垃圾桶的方法:
alias tcn='mv --force -t ~/.local/share/Trash '
該別名使用一個鮮為人知的 mv 標志(-t),使你能夠提供作為最終移動目標的參數,而忽略了首先列出要移動的文件的通常要求。現在,你可以使用新命令將文件和文件夾移動到系統垃圾桶:
$ lsfoo bar$ tcn foo$ lsbar
現在文件已“消失”,只有在你一頭冷汗的時候才意識到你還需要它。此時,你可以從系統垃圾桶中搶救該文件;這肯定可以給 Bash 和 mv 開發人員提供一些幫助。
注意:如果你需要一個具有更好的 FreeDesktop 兼容性的更強大的垃圾桶命令,請參閱 Trashy。
簡化 Git 工作流
每個人都有自己獨特的工作流程,但無論如何,通常都會有重復的任務。如果你經常使用 Git,那么你可能會發現自己經常重復的一些操作序列。也許你會發現自己回到主分支并整天一遍又一遍地拉取最新的變化,或者你可能發現自己創建了標簽然后將它們推到遠端,抑或可能完全是其它的什么東西。
無論讓你厭倦一遍遍輸入的 Git 魔咒是什么,你都可以通過 Bash 別名減輕一些痛苦。很大程度上,由于它能夠將參數傳遞給鉤子,Git 擁有著豐富的內省命令,可以讓你不必在 Bash 中執行那些丑陋冗長的命令。
例如,雖然你可能很難在 Bash 中找到項目的頂級目錄(就 Bash 而言,它是一個完全隨意的名稱,因為計算機的絕對頂級是根目錄),但 Git 可以通過簡單的查詢找到項目的頂級目錄。如果你研究過 Git 鉤子,你會發現自己能夠找到 Bash 一無所知的各種信息,而你可以利用 Bash 別名來利用這些信息。
這是一個來查找 Git 項目的頂級目錄的別名,無論你當前在哪個項目中工作,都可以將目錄改變為頂級目錄,切換到主分支,并執行 Git 拉取:
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 ]; thensource $HOME/.bash_functionsfi
在該函數文件中,添加這些代碼:
function cl() {DIR="$*";# if no DIR given, go homeif [ $# -lt 1 ]; thenDIR=$HOME;fi;builtin cd "${DIR}" && \# use your preferred ls commandls -F --color=auto}
將函數加載到 Bash 會話中,然后嘗試:
$ source ~/.bash_functions$ cl Documentsfoo bar baz$ pwd/home/seth/Documents$ cl ..Desktop Documents Downloads[...]$ pwd/home/seth
函數比別名更靈活,但有了這種靈活性,你就有責任確保代碼有意義并達到你的期望。別名是簡單的,所以要保持簡單而有用。要正式修改 Bash 的行為,請使用保存到 PATH 環境變量中某個位置的函數或自定義的 shell 腳本。
附注,有一些巧妙的奇技淫巧來實現 cd 和 ls 序列作為別名,所以如果你足夠耐心,那么即使是一個簡單的別名也永無止限。
開始別名化和函數化吧
可以定制你的環境使得 Linux 變得如此有趣,提高效率使得 Linux 可以改變生活。開始使用簡單的別名,進而使用函數,并在評論中發布你必須擁有的別名!


























