Bash

出自 Arch Linux 中文维基

Bash (Bourne-again Shell) 是一個來自 GNU命令行解釋器/程式語言。它的名字是向它的前身——很早以前的 Bourne shell 致敬。Bash可以運行在大部分類 UNIX 作業系統中,包括 GNU/Linux。

Bash是Arch Linux的默認命令行解釋器。

調用[編輯 | 編輯原始碼]

Bash 的運行方式會取決於 Bash 被調用的方式。下面是一些不同模式的描述。

如果 Bash 以TTY中的loginSSH 守護進程、或者其它類似的方式派生出來,我們稱之為登錄 (login) shell。你可以使用命令行選項 -l--login 來使用這種模式。

如果 Bash 的標準輸入輸出和標準錯誤輸出都連接到終端(比如說,一個終端模擬器),並且在啟動的時候既沒有使用 -c 選項和非選項參數(比如說,bash script),我們稱之為交互 (interactive) shell。所有的交互式 shell 都會執行/etc/bash.bashrc~/.bashrc 文件中的配置,而登錄shell還會執行/etc/profile~/.bash_profile 中的配置。

注意: 在 Arch Linux 中 /bin/sh (過去是 Bourne shell 的執行文件名) 是 bash 的符號連結。如果 Bash 通過 sh 方式調用,它會儘量模擬歷史上 sh 的啟動行為,包括 POSIX 兼容能力。

通過在Bash啟動時使用 --posix 命令行參數或者在啟動後執行 『set -o posix』 來使Bash在增強的POSIX標準下運行。

配置文件[編輯 | 編輯原始碼]

Bash會在啟動時按照不同的啟動方式執行一系列啟動文件。詳細描述請參考GNU Bash指南中/usr/share/doc/bash/bashref.html (Bash啟動文件)這一節。

文件 描述 登錄 shell

(見下)

交互 shell

非登錄

/etc/profile 加載全部儲存在 /etc/profile.d/*.sh/etc/bash.bashrc 中的配置。
~/.bash_profile 針對每個用戶,緊接 /etc/profile 執行。如果這個文件不存在,會順序檢查 ~/.bash_login~/.profile 文件。框架文件 /etc/skel/.bash_profile 同時會引用 ~/.bashrc
~/.bash_logout 針對每個用戶,退出登錄 shell 後。
/etc/bash.bash_logout 取決於 -DSYS_BASH_LOGOUT="/etc/bash.bash_logout" 編譯標記。退出登錄 shell 後。
/etc/bash.bashrc 取決於編譯標誌 -DSYS_BASHRC="/etc/bash.bashrc"。加載 /usr/share/bash-completion/bash_completion 配置。
~/.bashrc 針對每個用戶,在 /etc/bash.bashrc 後加載。
注意:

Shell 與環境變量[編輯 | 編輯原始碼]

Bash的行為和通過它啟動的程序會被許多環境變量影響。環境變量用於儲存有用的值,比如命令搜索路徑,或者默認瀏覽器。當一個新的 shell 或者腳本被啟動時,這個 shell 會繼承它的父進程的環境變量,從而這個 shell 會帶有內部 shell 變量[1]

這些內部 shell 變量可以以此導出以變成環境變量:

VARIABLE=content
export VARIABLE

或者

export VARIABLE=content

環境變量依照慣例放置在~/.profile或者/etc/profile中,這樣其他兼容 Bourne shell 的 shell 也可以使用。

關於更詳盡的內容,您可以參考Environment variables

命令行[編輯 | 編輯原始碼]

Bash 的命令行由一個叫做 Readline 的分離庫來管理。Readline 提供了emacsvi 風格的快捷鍵用於操作命令行,比如說,以單詞為基準前後移動、刪除等。管理輸入歷史也是 Readline 的職責。它還允許你創造

Tab 鍵補全[編輯 | 編輯原始碼]

Tab 鍵補全,提供在按下 tab 鍵後自動補全命令的功能(這個功能默認啟用)。

Tab 按下的次數[編輯 | 編輯原始碼]

可能最多需要按三次 tab 才能顯示所有的補全選項。如果希望減少這個數值,請參考 更快的補全操作

常用命令的選項補全[編輯 | 編輯原始碼]

通常來講,Bash 中按下 tab 只會補全命令、文件名和變量。安裝 bash-completion 包,並加載 /usr/share/bash-completion/bash_completion 文件中的配置(這個文件應該已經在Arch的/etc/bash.bashrc中加載了),可以提供更多針對常見命令的選項的 tab 補全。安裝這個包後,常規的補全(比如說 ls file.* Tab Tab)可能會表現得不同。但是,您可以通過{ic|compopt -o bashdefault program}}命令來重新啟用。(更多細節,請參考 [2] and [3]。)

自定義命令補全[編輯 | 編輯原始碼]

注意: 使用 complete 功能可能與 bash-completion 衝突。

通常來講,Bash 中按下 tab 只會補全命令後的文件名。通過complete -c命令,Bash 可以規定某些命令後的補全形式為命令,比如:

~/.bashrc
complete -c man which

或通過-cf命令,規定補全形式為命令和文件,比如:

complete -cf sudo

更多補全形式,請參考手冊bash(1) § Programmable Completion

歷史[編輯 | 編輯原始碼]

歷史補全[編輯 | 編輯原始碼]

您可以綁定上下鍵來在 Bash 的歷史中查找(請參考 Readline#歷史 and Readline 啟動文件語法):

~/.bashrc
 bind '"\e[A": history-search-backward'
 bind '"\e[B": history-search-forward'

或者所有 Readline 程序:

~/.inputrc
"\e[A": history-search-backward
"\e[B": history-search-forward

更近的歷史記錄[編輯 | 編輯原始碼]

HISTCONTROL變量可以避免歷史記錄記錄特定的命令。

不記錄連續重複的命令:

~/.bashrc
export HISTCONTROL=ignoredups

歷史記錄中重複命令(無論是否連續)只記錄最後一條:

~/.bashrc
export HISTCONTROL=erasedups

不記錄空格開頭的命令:

~/.bashrc
export HISTCONTROL=ignorespace

不記錄連續重複的命令、空格開頭的命令:

~/.bashrc
export HISTCONTROL=ignoreboth

重複命令只記錄最後一條,且不記錄空格開頭的命令:

~/.bashrc
export HISTCONTROL="erasedups:ignorespace"

更多選項,請參考手冊bash(1) § HISTCONTROL

禁用歷史記錄[編輯 | 編輯原始碼]

臨時禁用歷史記錄:

$ set +o history

現在輸入的命令將不會存入$HISTFILE

比如說,你現在可以執行 printf secret | sha256sum 來生成密碼文件的散列值,或是隱藏您使用GPG的歷史,如執行gpg -eaF secret-pubkey.asc命令。這些秘密不會被寫入磁碟。

開啟歷史記錄:

$ set -o history

禁用所有的 Bash 歷史:

~/.bashrc or /etc/profile
export HISTSIZE=0

為了保險(這會永遠清除所有的歷史記錄):

$ wipe -i -l2 -x4 -p4 "$HISTFILE"
$ ln -sv /dev/null "$HISTFILE"

模仿 Zsh 的幫助功能[編輯 | 編輯原始碼]

Zsh 可以在光標指向命令的時候按 Alt+h 來調用這個命令的手冊。 相同的行為可以通過這個 Readline 綁定在 Bash 中開啟:

~/.bashrc
run-help() { help "$READLINE_LINE" 2>/dev/null || man "$READLINE_LINE"; }
bind -m vi-insert -x '"\eh": run-help'
bind -m emacs -x     '"\eh": run-help'

這個操作假設你使用(默認的)Emacs 編輯模式

別名[編輯 | 編輯原始碼]

別名(alias)是可以讓您用另一個字符串來替換一個字符串的命令。這個命令常常被用來縮短系統命令,或者用來將默認參數加入到常用命令中。

針對用戶的別名可以保存在~/.bashrc, 或任意~/.bashrc加載的腳本。系統級的別名(這些會影響所有用戶)存放在/etc/bash.bashrc。別名示例可參考 [4]

關於函數,請參考 函數

提示與技巧[編輯 | 編輯原始碼]

自定義提示符[編輯 | 編輯原始碼]

參見 自定義提示符

語法高亮與自動提示[編輯 | 編輯原始碼]

blesh-gitAUR is a command line editor written in pure Bash which replaces Readline. It has many enhanced features like syntax highlighting, autosuggestions, menu-completion, abbreviations, Vim editing mode, hook functions, and more.

After installing it, source it in an interactive session. Configurations are explained in depth in the ~/.blerc file and at the wiki. The stable bleshAUR package is also available.

找不到命令[編輯 | 編輯原始碼]

pkgfile 提供了一個"找不到命令"的鉤子,可以在輸入未知命令後自動查找官方的軟體包。

你需要加載這個鉤子來啟用它,如下:

~/.bashrc
source /usr/share/doc/pkgfile/command-not-found.bash

現在,運行一個不可用的命令將會顯示如下信息:

$ abiword
abiword may be found in the following packages:
  extra/abiword 3.0.1-2	/usr/bin/abiword
注意: 需要先更新 pkgfile 的資料庫才能運作。更多細節,請參考pkgfile#安裝

在終端內禁用Ctrl+Z[編輯 | 編輯原始碼]

你可以像這樣包裝你的命令,來關閉 Ctrl+Z 功能(暫停/關閉程序)。通過在這個腳本中包裝命令

#!/bin/bash
trap "" 20
adom

這時如果你在玩 adomAUR 要按 Shift+Z 組合鍵時不小心按下了 Ctrl+Z 組合鍵,你的遊戲就不會停止運行了,因為我們已經禁用了Ctrl+Z

登出後清空屏幕[編輯 | 編輯原始碼]

當登出虛擬終端時,清空屏幕:

~/.bash_logout
clear
reset

輸入路逕自動添加"cd"[編輯 | 編輯原始碼]

Bash 可以自動在輸入的一個路徑前添加 cd 。比如說:

$ /etc
bash: /etc: Is a directory

但是如果在 .bashrc 文件裡添加一行:

~/.bashrc
...
shopt -s autocd
...

你會得到:

[user@host ~]$ /etc
cd /etc
[user@host etc]$

自動跳轉[編輯 | 編輯原始碼]

Python腳本autojump-gitAUR 允許在用戶訪問最多的路徑中搜索文件系統。

安裝完後,加載 /etc/profile.d/autojump.bash 來啟動這項功能。

zoxideautojump的功能性能增強版,可直接替代。

防止覆蓋文件[編輯 | 編輯原始碼]

在當前的會話中,防止 shell 輸出重定向覆蓋一個已有的文件:

$ set -o noclobber

這和set -C命令是一樣的。

如果想讓該用戶一直生效:

~/.bashrc
...
set -o noclobber

在設定 noclobber 的情況下強制覆蓋文件:

$ echo "output" >| file.txt

使用目錄堆棧切換目錄[編輯 | 編輯原始碼]

pushdpopd以堆棧的方式控制目錄切換,利於「撤銷」目錄切換動作。

 [user@host ~] pushd /tmp/dir1
 [user@host /tmp/dir1] pushd /var/lib
 [user@host/var/lib] popd
 [user@host/tmp/dir1] popd
 [user@host ~]

參見bash(1) § DIRSTACK

GNU readline alternative[編輯 | 編輯原始碼]

ble.sh, packed as bleshAUR and blesh-gitAUR, is a full-featured line editor written in pure Bash. It is an alternative to GNU readline. It offers syntax highlighting, enhanced completion, vim editing mode, and other interesting features include status line, history share, right prompt, transient prompt, xterm title, etc.

錯誤排除[編輯 | 編輯原始碼]

修正窗口大小調整時的換行[編輯 | 編輯原始碼]

如果您調整了終端模擬器的大小,Bash 可能並沒有得到大小重調的信號,你鍵入的文本就不會正確的換行,並且與已輸入內容重疊。啟用 checkwinsize 選項可以在每一個命令後檢查窗口的大小,並按需更新 LINESCOLUMNS 的值來調整。

~/.bashrc
shopt -s checkwinsize

設置 ignoreeof 後 shell 仍然退出[編輯 | 編輯原始碼]

如果您設置了 ignoreeof 選項,但是如果重複按下 ctrl-D shell 仍然會退出。因為這個選項只允許忽略 10 次連續的EOF記號(即 Ctrl+D)。

如果需要將這個次數調的更高,需要使用 IGNOREEOF 變量。

比如:

export IGNOREEOF=100

分析代碼以檢查錯誤[編輯 | 編輯原始碼]

shellcheck 可以分析bash腳本(以及其他腳本),顯示可能存在的問題,並對優化代碼質量提出意見。

shellcheck.net 網站也提供了基於此程序的相同功能。

更多信息 (英語)[編輯 | 編輯原始碼]

教程[編輯 | 編輯原始碼]

社區[編輯 | 編輯原始碼]

例子[編輯 | 編輯原始碼]