Bash

如何檢查 $PWD 是否是給定路徑的子目錄

  • February 3, 2022

例如檢查是否$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)"/*) …

zshshell 也有自己的帶有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; })"/*) …

引用自:https://unix.stackexchange.com/questions/6435