
我可以在 shell(恰好是bash
)中輸入什麼來列出所有可識別的命令?
另外,這因外殼而異嗎?或者所有 shell 都只有一個它們識別的命令“目錄”?
其次,不同的問題,但我怎麼能涵蓋其中任何一個?換句話說,我如何編寫自己的view
命令來替換 Ubuntu 系統上現有的命令,該命令似乎只是加載vim
.
答案1
您可以使用compgen
compgen -c # will list all the commands you could run.
供參考:
compgen -a # will list all the aliases you could run.
compgen -b # will list all the built-ins you could run.
compgen -k # will list all the keywords you could run.
compgen -A function # will list all the functions you could run.
compgen -A function -abck # will list all the above in one go.
答案2
shell 知道四種指令。
- 別名:這些是帶有某些選項的命令的暱稱。它們在 shell 的初始化檔案(對於 bash)中定義
~/.bashrc
。 - 函數:它們是具有名稱的 shell 程式碼片段。與別名一樣,它們是在 shell 的初始化檔案中定義的。
- 內建指令:shell 附有少量內建指令。大多數內建指令都會操縱 shell 狀態(
cd
變更目前目錄、set
變更選項和位置參數、export
變更環境等)。大多數 shell 都提供基本相同的內建函數,但每個 shell 對基本集都有一些擴展。 - 外部命令:它們獨立於 shell。與其他程式一樣,shell 透過在可執行搜尋路徑。環境
PATH
變數包含以冒號分隔的目錄列表,用於搜尋程式。
如果存在同名的多種類型的命令,則執行上述順序中的第一個符合項目。
您可以透過執行來查看名稱對應的命令類型type some_name
。
您可以透過執行alias
不帶參數的內建函數來列出別名。無法列出適用於所有 shell 的函數或內建函數。您可以在 shell 的文檔中找到內建指令的清單。
在 bash 中,set
內建函數列出了函數及其定義和變數。在 bash、ksh 或 zsh 中,typeset -f
列出函數及其定義。在 bash 中,您可以列出任何類型的所有命令名稱compgen -c
。您可以使用compgen -A alias
,compgen -A builtin
compgen -A function
列出特定類型的命令。您可以傳遞一個附加字串來compgen
僅列出以該前綴開頭的命令。
echo ${(k)aliases}
在 zsh 中,您可以使用、echo ${(k)functions}
和列出給定類型的目前可用命令echo ${(k)builtins}
(echo ${(k)commands}
最後一個僅列出外部命令)。
以下與 shell 無關的程式碼片段列出了所有可用的外部程式:
case "$PATH" in
(*[!:]:) PATH="$PATH:" ;;
esac
set -f; IFS=:
for dir in $PATH; do
set +f
[ -z "$dir" ] && dir="."
for file in "$dir"/*; do
if [ -x "$file" ] && ! [ -d "$file" ]; then
printf '%s = %s\n' "${file##*/}" "$file"
fi
done
done
Bash 中有一個邊緣情況:散列命令。
只有在雜湊表中找不到該指令時,才會對 $PATH 中的目錄執行完整搜尋
嘗試:
set -h
mkdir ~/dir-for-wat-command
echo 'echo WAT!' >~/dir-for-wat-command/wat
chmod +x ~/dir-for-wat-command/wat
hash -p ~/dir-for-wat-command/wat wat
wat
環境PATH
變數不包含~/dir-for-wat-command
,compgen -c
不顯示wat
,但可以運行wat
。
如果您想隱藏現有命令,定義別名或函數。
¹例外:一些內建函數(稱為特殊的內建函數) 不能被函數遮蓋-儘管 bash 和 zsh 在預設模式下在這一點上不符合 POSIX。
答案3
嘗試這個,使用巴什:
( # usage of a sub processus: the modificaion of PATH variable is local in ( )
PATH+=:EOF # little hack to list last PATH dir
printf '%s\n' ${PATH//:/\/* }
)
答案4
如果按兩次 Tab 鍵,然後按 y,您將獲得目前 shell 中所有可用指令的清單。對於第二個問題,我認為你應該使用別名:外殼別名。