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 的執行文件名) 是 /bin/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的手冊頁。

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

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

您可以綁定上下鍵來在 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

將其設置為 erasedups 可以讓 Bash 的歷史記錄對一條命令只保留一個歷史記錄(與順序無關)。更多選項,請參考Bash的手冊頁。

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

臨時禁用歷史記錄:

$ set +o history

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

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

開啟歷史記錄:

$ set -o history
提示:如果 HISTCONTROL 變量包含了 ignorespace,以空格開頭的命令將不會記入歷史。這樣可以更加方便地控制歷史記錄。更多細節,請參考bash(1) § Shell Variables

禁用所有的 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, 而將系統級的別名(這些會影響所有用戶)存放在/etc/bash.bashrc。別名的示例,請參考 [4]

關於函數,請參考 函數

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

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

參見 自定義提示符

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

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]$

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

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

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

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

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

$ set -o noclobber

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

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

~/.bashrc
...
set -o noclobber

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

$ echo "output" >| file.txt

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

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

如果您調整了終端模擬器的大小,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 網站也提供了基於此程序的相同功能。

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

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

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

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