如何创建 bash 和 zsh(便携式)函数来检查一个路径是否是另一个路径的子路径?

How to create bash and zsh (portable) function that checks if one path is a subpath of another?

我认为 bash 这应该很容易,但不幸的是不。

我目前的尝试是

path_outside_another() {
    PATH=
    ANOTHER_PATH=
    if ${$PATH%$ANOTHER_PATH} !=  then
        echo "inside"
    else
        echo "not inside"
    fi
    return 0
}

编辑

在你的帮助下,我能够创建这个

path_starts_with_another_path() {


    path1=
    path2=

    if [[ $path1 == "$path2"* ]]; then
        echo "yes"
    else
        echo "no"
    fi
}

if [[ $whole_path == *$small_path* ]] then echo 'inside' else echo 'not' fi

从正确的实施开始,讨论差异:

path_outside_another() {
  local path another_path
  path=$(readlink -m "")
  another_path=$(readlink -m "")
  if [[ "${path#$another_path}" != "$path" ]]; then
    echo "$path starts with with $another_path"
  else
    echo "$path does not start with $another_path"
  fi
}

同时考虑:

if [[ $path = "$another_path"* ]]; then
  echo "$path starts with $another_path"
else
  echo "$path does not start with $another_path"
fi

用法:

$ path_outside_another /tmp /tmp/foobar
/tmp does not start with /tmp/foobar
$ path_outside_another /tmp/foobar /tmp
/tmp/foobar starts with /tmp
  • if 的参数必须是命令。这可以是外部命令如grep,内置命令如[,也可以是扩展语法指定的命令如[[,但必须是命令;相比之下,$foo != $bar 将简单地尝试 运行 通过扩展 $foo 生成的第一个单词作为命令,并将 != 作为参数传递。参见 the bash-hackers page on the if clause
  • 如果您希望将变量值的更改保留在该函数的本地,则必须在函数内将变量声明为 local;默认情况下,分配是全局的,如果分配给环境变量共享的名称,新值将自动导出到环境中。参见 variable scope in the bash-hackers wiki
  • 使用$PATH 覆盖用于查找其他程序的环境变量。不要那样做。请参阅 the POSIX specification on environment variables 指定全大写名称保留供系统使用。
  • 语法是 ${path},而不是 ${$path},即使在参数化扩展时也是如此。参见 the bash-hackers page on parameter expansion
  • 使用readlink -m确保两个路径都是完全合格的,因此这是一个子路径检查,即使一个或两个在提供时是相对的。如果您的平台不提供 readlink -m,请参阅 How can I get the behavior of GNU's readlink -f on a Mac?