Bash
Bash (Bourne-again Shell) 是一個來自 GNU的命令行解釋器/編程語言。它的名字是向它的前身——很早以前的 Bourne shell 致敬。Bash可以運行在大部分類 UNIX 操作系統中,包括 GNU/Linux。
Bash是Arch Linux的默認命令行解釋器。
調用[編輯 | 編輯原始碼]
Bash 的運行方式會取決於 Bash 被調用的方式。下面是一些不同模式的描述。
如果 Bash 以TTY中的login
、SSH 守護進程、或者其它類似的方式派生出來,我們稱之為登錄 (login) shell。你可以使用命令行選項 -l
或 --login
來使用這種模式。
如果 Bash 的標準輸入輸出和標準錯誤輸出都連接到終端(比如說,一個終端模擬器),並且在啟動的時候既沒有使用 -c
選項和非選項參數(比如說,bash script
),我們稱之為交互 (interactive) shell。所有的交互式 shell 都會執行/etc/bash.bashrc
和 ~/.bashrc
文件中的配置,而登錄shell還會執行/etc/profile
和 ~/.bash_profile
中的配置。
/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 後加載。
|
否 | 是 |
- 如果以
--login
調用,登錄 shell 可能不是交互式的。 - 如果可以交互,非登錄 shell 不會 加載
~/.bash_profile
。它會繼承調用他們的父進程(可能是一個登錄 shell)的環境參數。更多信息,請參考GregsWiki:ProcessManagement#On processes, environments and inheritance。
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 提供了emacs 和 vi 風格的快捷鍵用於操作命令行,比如說,以單詞為基準前後移動、刪除等。管理輸入歷史也是 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
在終端內禁用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
選項可以在每一個命令後檢查窗口的大小,並按需更新 LINES
和 COLUMNS
的值來調整。
~/.bashrc
shopt -s checkwinsize
設置 ignoreeof 後 shell 仍然退出[編輯 | 編輯原始碼]
如果您設置了 ignoreeof
選項,但是如果重複按下 ctrl-D
shell 仍然會退出。因為這個選項只允許忽略 10 次連續的EOF記號(即 Ctrl+D
)。
如果需要將這個次數調的更高,需要使用 IGNOREEOF 變量。
比如:
export IGNOREEOF=100
分析代碼以檢查錯誤[編輯 | 編輯原始碼]
包 shellcheck包 可以分析bash腳本(以及其他腳本),顯示可能存在的問題,並對優化代碼質量提出意見。
shellcheck.net 網站也提供了基於此程序的相同功能。
更多信息 (英語)[編輯 | 編輯原始碼]
- Wikipedia:Bash (Unix shell)
- Bash 參考手冊,或是
/usr/share/doc/bash/bashref.html
- Readline 啟動文件語法
- The Bourne-Again Shell - 開源軟件架構 第三章
- PS1 生成器 - 生成你的 .bashrc/PS1 腳本,這樣就可以在命令行中使用鼠標拖拽了。
- 有用的 .bashrc 命令
教程[編輯 | 編輯原始碼]
- Greg's Wiki
- GregsWiki:BashGuide
- GregsWiki:BashFAQ
- Bash Hackers Wiki
- Bash Hackers Wiki: List of Bash online tutorials
- Quote Tutorial