如何创建bash和zsh(可移植)函数来检查一条路径是否是另一条路径的子路径?

时间:2015-12-17 18:36:43

标签: bash zsh

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

我目前的尝试是

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

修改

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

path_starts_with_another_path() {


    path1=$1
    path2=$2

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

2 个答案:

答案 0 :(得分:1)

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

path_outside_another() {
  local path another_path
  path=$(readlink -m "$1")
  another_path=$(readlink -m "$2")
  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?

答案 1 :(得分:0)

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