如何创建 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?
我认为 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 theif
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?