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 的執行文件名) 是 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 也可以使用。
關於更詳盡的內容,您可以參考環境變量。
命令行[編輯 | 編輯原始碼]
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
)可能會表現得不同。但是,您可以通過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 編輯模式。
[編輯 | 編輯原始碼]
atuin包 replaces your existing shell history with an SQLite database, and records additional context for your commands. Additionally, it provides optional and fully encrypted synchronization of your history between machines, via an Atuin server.
Enable bash history timestamps (export HISTTIMEFORMAT="%F %T "
) before syncing. Atuin works well with tools like blesh-gitAUR and cmd-wrapped to provide an enhanced terminal experience across machines.
別名[編輯 | 編輯原始碼]
別名(alias)是可以讓您用另一個字符串來替換一個字符串的命令。這個命令常常被用來縮短系統命令,或者用來將默認參數加入到常用命令中。
針對用户的別名可以保存在~/.bashrc
, 或任意~/.bashrc
中加載的腳本。系統級的別名(這些會影響所有用户)存放在/etc/bash.bashrc
。別名示例可參考 [4]。
關於函數,請參考函數。
提示與技巧[編輯 | 編輯原始碼]
自定義提示符[編輯 | 編輯原始碼]
參見自定義提示符。
語法高亮與自動提示[編輯 | 編輯原始碼]
ble.sh (Bash Line Editor), packed as blesh-gitAUR, is a command line editor written in pure Bash, which is an alternative to GNU Readline. It has many enhanced features like syntax highlighting, autosuggestions, menu-completion, abbreviations, Vim editing mode, and hook functions. Other interesting features include status line, history share, right prompt, transient prompt, and xterm title.
After installing it, source it in an interactive session.
~/.bashrc
source /usr/share/blesh/ble.sh
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
在終端內禁用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
來啟動這項功能。
zoxide包是autojump
的功能性能增強版,可直接替代。
防止覆蓋文件[編輯 | 編輯原始碼]
在當前的會話中,防止 shell 輸出重定向覆蓋一個已有的文件:
$ set -o noclobber
這和set -C
命令是一樣的。
如果想讓該用户一直生效:
~/.bashrc
... set -o noclobber
在設定 noclobber
的情況下強制覆蓋文件:
$ echo "output" >| file.txt
使用目錄堆棧切換目錄[編輯 | 編輯原始碼]
pushd
與popd
以堆棧的方式控制目錄切換,利於「撤銷」目錄切換動作。
[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 可能並沒有得到大小重調的信號,你鍵入的文本就不會正確的換行,並且與已輸入內容重疊。啟用 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 命令