如何檢查 $PWD 是否是給定路徑的子目錄
例如檢查是否
$PWD
是/home 的子目錄。換句話說,我正在尋找一個 bash 字元串操作來檢查一個字元串是否以另一個字元串開頭。
如果您想可靠地測試一個目錄是否是另一個目錄的子目錄,您需要的不僅僅是字元串前綴檢查。Gilles 的回答詳細描述瞭如何正確進行此測試。
但是如果你確實想要一個簡單的字元串前綴檢查(也許你已經規範了你的路徑?),這是一個很好的:
test "${PWD##/home/}" != "${PWD}"
如果
$PWD
以 “/home/” 開頭,它會在左側被剝離,這意味著它不會匹配右側,所以 “!=” 返回 true。
在任何 Bourne 風格的 shell 中測試一個字元串是否是另一個字元串的前綴:
case $PWD/ in /home/*) echo "home sweet home";; *) echo "away from home";; esac
相同的原則適用於後綴或子字元串測試。請注意,在
case
構造中,與文件名不同,它*
匹配任何字元,包括 a/
或首字母.
.在實現
[[ … ]]
語法的 shell(即 bash、ksh 和 zsh)中,它可用於將字元串與模式匹配。(請注意,該[
命令只能測試字元串是否相等。)if [[ $PWD/ = /home/* ]]; then …
如果你專門測試目前目錄是否在下面
/home
,那麼一個簡單的子字元串測試是不夠的,因為符號連結。如果
/home
是它自己的文件系統,則測試目前目錄 (.
) 是否在該文件系統上。if [ "$(df -P . | awk 'NR==2 {print $6}')" = "/home" ]; then echo 'The current directory is on the /home filesystem' fi
如果您有 NetBSD、OpenBSD 或 GNU 或 busybox 或 toybox
readlink
(最後 3 個常見於基於 Linux 的系統,如 Debian、OpenWrt 或 Android),您可以使用readlink -f
從路徑中去除符號連結。case $(readlink -f .)/ in "$(readlink -f /home)"/*) …
一些系統也有一個
realpath
命令(也在 GNU 工具箱中,它在readlink
這些天是首選的):case $(readlink -f .)/ in "$(readlink -f /home)"/*) …
zsh
shell 也有自己的帶有realpath()
修飾符的運算符:P
:if () [[ $1:P/ = $2:P/* ]] . /home; then …
否則,您可以使用
pwd
來顯示目前目錄。cd
但是,如果您的 shell 跟踪命令並保留用於訪問目錄的名稱而不是其“實際”位置,則必須注意不要使用內置的 shell 。case $(pwd -P 2>/dev/null || env PWD= pwd)/ in "$(cd /home && { pwd -P 2>/dev/null || env PWD= pwd; })"/*) …