如何检查 $PWD 是否是给定路径的子目录

如何检查 $PWD 是否是给定路径的子目录

例如检查是否$PWD是/home 的子目录。换句话说,我正在搜索 bash 字符串操作来检查一个字符串是否以另一个字符串开头。

答案1

要在任何 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 $(realpath .)/ in "$(realpath /home)"/*) …

shellzsh也有自己的realpath()带有:P修饰符的运算符:

if () [[ $1:P/ = $2:P/* ]] . /home; then …

否则,您可以使用pwd显示当前目录。但是,如果您的 shell 跟踪cd命令并保留用于访问目录的名称而不是其“实际”位置,则必须注意不要使用内置 shell 。

case $(pwd -P 2>/dev/null || env PWD= pwd)/ in
  "$(cd /home && { pwd -P 2>/dev/null || env PWD= pwd; })"/*) …

答案2

如果您想可靠地测试一个目录是否是另一个目录的子目录,您需要的不仅仅是字符串前缀检查。吉尔斯的回答详细描述了如何正确进行此测试。

但如果您确实想要一个简单的字符串前缀检查(也许您已经规范化了路径?),这是一个很好的选择:

test "${PWD##/home/}" != "${PWD}"

如果$PWD以“/home/”开头,它会在左侧被剥离,这意味着它不会与右侧匹配,因此“!=”返回 true。

答案3

粗制版:

[ "${PWD:0:6}" = /home/ ]

缺点是必须先计算字符数,并且不能/home/用诸如 之类的通用内容替换$1

编辑(感谢@Michael)进行概括以与$VAR可以使用的进行比较

[ "${PWD:0:${#VAR}}" = "$VAR" ]

答案4

我不太明白这个问题,但要找到的父母$PWD, 做dirname -- "$PWD"。要查找父级的父级,请运行dirname -- "$(dirname -- "$PWD")",等等......

相关内容