bash pathmunge 与 grep 相比有什么优势?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5012958/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the advantage of pathmunge over grep?
提问by Parag Doke
Currently working on Solaris 10 in the bash shell. While looking at a script, I noticed the pathmunge procedure set up to avoid duplication of folder paths in the PATH (it also seems to have the feature to add the necessary folder at the beginning or the end of the PATH).
目前正在 bash shell 中处理 Solaris 10。在查看脚本时,我注意到 pathmunge 过程的设置是为了避免 PATH 中文件夹路径的重复(它似乎也具有在 PATH 的开头或结尾添加必要文件夹的功能)。
Apart from the ability to append/pre-pend (pardon if that is the wrong term) to the PATH, why cannot we simply do an echo ${PATH} | grep <folder one wishes to add>?
除了能够附加/预先挂起(如果这是错误的术语,请原谅)到 PATH,为什么我们不能简单地做一个echo ${PATH} | grep <folder one wishes to add>?
If my only intent is to have a certain folder in the PATH (and not really concerned about the beginning or end), would a grep serve the purpose?
如果我的唯一目的是在 PATH 中有一个特定的文件夹(而不是真正关心开始或结束),那么 grep 能达到目的吗?
回答by Ori
Until 2012, pathmunge used to use grep itself. (Well, egrep, to be precise.)
直到 2012 年,pathmunge 过去一直使用 grep 本身。(好吧,egrep,准确地说。)
In Red Hat, CentOS, etc. pathmunge is defined in /etc/profile:
在 Red Hat、CentOS 等中,pathmunge 定义在/etc/profile:
pathmunge () {
if ! echo $PATH | /bin/egrep -q "(^|:)($|:)" ; then
if [ "" = "after" ] ; then
PATH=$PATH:
else
PATH=:$PATH
fi
fi
}
As you can see, it's slightly more sophisticated than what you propose to do, but not much. The reason your proposal wouldn't work is that without the delimiters it'll make partial matches.
如您所见,它比您打算做的稍微复杂一些,但并不多。您的提议不起作用的原因是,如果没有分隔符,它将进行部分匹配。
so if my path is /usr/local/sbin:/usr/local/bin, echo ${PATH} | grep /usr/localwill return true, even though /usr/local isn't in my path. So you need to match the delimiters. But if you grep for :/usr/local:you'll also fail, because you won't ever match the first or last item in the path, since $PATH neither starts nor ends with delimiter. That's why egrep is used. (^|:) matches either a colon or the beginning of the line. ($|:) matches either a colon or the end of the line.
因此,如果我的路径是/usr/local/sbin:/usr/local/bin,echo ${PATH} | grep /usr/local即使 /usr/local 不在我的路径中,也会返回 true。所以你需要匹配分隔符。但是如果你 grep for:/usr/local:你也会失败,因为你永远不会匹配路径中的第一个或最后一个项目,因为 $PATH 既不以分隔符开头也不以分隔符结尾。这就是使用 egrep 的原因。(^|:) 匹配冒号或行首。($|:) 匹配冒号或行尾。
Modern versions of pathmunge use the shell's built-in pattern-matching capabilities, which is a little more efficient.
现代版本的 pathmunge 使用 shell 的内置模式匹配功能,效率更高一些。
回答by scavenger
I propose an evolution to pathmunge, which I use for 2 years now.
我提出了对 pathmunge 的演变,我现在使用了 2 年。
pathmunge() {
if [ -d "" ]; then
realpath / 2>&1 >/dev/null && path=$(realpath "") || path=""
# GNU bash, version 2.02.0(1)-release (sparc-sun-solaris2.6) ==> TOTAL incompatibility with [[ test ]]
[ -z "$PATH" ] && export PATH="$path:/bin:/usr/bin"
# SunOS 5.6 ==> (e)grep option "-q" not implemented !
/bin/echo "$PATH" | /bin/egrep -s "(^|:)$path($|:)" >/dev/null || {
[ "" == "after" ] && export PATH="$PATH:$path" || export PATH="$path:$PATH"
}
fi
}
1) It checks for validity of the directory, for a minimal performance cost
1) 它检查目录的有效性,以最小的性能成本
2) It uses realpath as well, and the command realpath is tested as well. realpath your paths before adding it to $PATH
2)它也使用realpath,并且也测试了命令realpath。在将它添加到 $PATH 之前真实路径你的路径
3) egrep -q is unavailable on SunOS 5.6 (yes it is still in use in many companies)
3) egrep -q 在 SunOS 5.6 上不可用(是的,它仍在许多公司中使用)

