# Check that the specified directory exists – and is in the PATH.
is_dir_in_path()
{
if [ -z "${1:-}" ]; then
printf "The path to a directory must be provided as an argument.\n" >&2
return 1
fi
# Check that the specified path is a directory that exists.
if ! [ -d "$1" ]; then
printf "Error: ‘%s’ is not a directory.\n" "$1" >&2
return 1
fi
# Use absolute path for the directory if a relative path was specified.
if command -v readlink >/dev/null ; then
dir="$(readlink -f "$1")"
elif command -v realpath >/dev/null ; then
dir="$(realpath "$1")"
else
case "$1" in
/*)
# The path of the provided directory is already absolute.
dir="$1"
;;
*)
# Prepend the path of the current directory.
dir="$PWD/$1"
;;
esac
printf "Warning: neither ‘readlink’ nor ‘realpath’ are available.\n"
printf "Ensure that the specified directory does not contain ‘..’ in its path.\n"
fi
# Check that dir is in the user’s PATH.
case ":$PATH:" in
*:"$dir":*)
printf "‘%s’ is in the PATH.\n" "$dir"
return 0
;;
*)
printf "‘%s’ is not in the PATH.\n" "$dir"
return 1
;;
esac
}
9条答案
按热度按时间fxnxkyjh1#
使用
grep
是多余的,如果您搜索的内容碰巧包含RE元字符,可能会引起麻烦。这个问题可以使用bash的内置[[
命令很好地解决:注意,在$PATH的扩展和要搜索的路径之前添加冒号解决了子字符串匹配问题;双引号路径避免了元字符的麻烦。
2eafrhcq2#
绝对没有必要为此使用像
grep
这样的外部实用程序。下面是我一直在使用的,它应该可以移植回甚至是Bourne shell的遗留版本。krugob8w3#
下面是不使用
grep
的方法:这里的关键是使用
?()
结构使冒号和通配符成为可选的,这种形式的元字符应该没有任何问题,但是如果你想包含引号,这就是它们的位置:这是使用match运算符(
=~
)的另一种方法,因此语法更像grep
:vvppvyoh4#
很简单很天真的事:
无论你要找什么,你都可以把
$?
放进一个变量中,或者使用一个合适的if
语句。局限性包括:
或者使用perl一行程序:
这仍然有一个限制,即它不会执行任何shell扩展,但是如果有一个子字符串匹配,它也不会失败(上面匹配“
/usr/bin
“,以防这一点不清楚)。bqujaahr5#
下面是一个纯粹的bash实现,它不会因为部分匹配而导致误报。
从3.0版开始,=~操作符使用了bash中提供的正则表达式模式支持。检查了三个模式,由正则表达式的OR操作符
|
分隔。所有三个子模式都相对相似,但是它们的差异对于避免部分匹配非常重要。
在正则表达式中,
^
匹配行首,$
匹配行尾。只有当第一个模式查找的路径是$PATH中的第一个值时,第一个模式才会计算为true。只有当第三个模式查找的路径是$PATH中的最后一个值时,第三个模式才会计算为true。当第二个模式找到它要查找的路径时,第二个模式才会计算为true。s查找介于其他值之间的值,因为它查找的是$PATH变量使用的分隔符:
,位于所搜索路径的两侧。gwbalxhn6#
我编写了以下shell函数来报告当前
PATH
中是否列出了某个目录。此函数与POSIX兼容,可以在Dash和Bash等兼容的shell中运行(不依赖于Bash特有的特性)。它包括将相对路径转换为绝对路径的功能。它使用
readlink
或realpath
实用程序来完成此操作,但如果提供的目录没有..
或其他链接作为其路径的组成部分,则不需要这些工具。除此之外,该函数不需要任何 shell 外部的程序。使用
:$PATH:
的部分确保了如果所需路径是PATH
中的第一个或最后一个条目,模式也会匹配。jq6vz3qz7#
这是一种暴力破解的方法,但它在所有情况下都有效,除非路径项包含冒号,并且除了shell之外不使用其他程序。
whlutmcx8#
$PATH
是以:
分隔的字符串列表,用于描述目录列表。目录是以/
分隔的字符串列表。两个不同的字符串可以指向同一目录(如$HOME
和~
,或者/usr/local/bin
和/usr/local/bin/
)。所以我们必须修正我们要比较/检查的规则。我建议比较/检查整个字符串,而不是物理目录,但是去除重复的和尾随的/
。首先从
$PATH
中删除重复和尾随的/
:现在假设
$d
包含您要检查的目录,然后通过管道传输前面的命令来检查$PATH
中的$d
。bvjveswy9#
更好更快的解决方案是:
我个人在我的bash提示符中使用它来在我转到$PATH中的目录时添加图标。