2011-02-16 92 views
6

目前在bash shell中使用Solaris 10。 查看脚本时,我注意到设置了pathmunge过程以避免PATH中的文件夹路径重复(它也似乎具有在PATH开头或结尾添加必要文件夹的功能)。pathmunge优于grep的优势是什么?

除了PATH附加/预先挂钩(如果这是一个错误的术语)的能力,为什么我们不能简单地做一个echo ${PATH} | grep <folder one wishes to add>

如果我唯一的意图是在PATH中有一个特定的文件夹(而不是真的担心开始或结束),grep是否会达到目的?

回答

9

pathmunge使用grep本身。 (好吧,egrep的,要精确。)

在红帽,CentOS的,等pathmunge在/etc/profile定义:

pathmunge() { 
     if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then 
      if [ "$2" = "after" ] ; then 
       PATH=$PATH:$1 
      else 
       PATH=$1:$PATH 
      fi 
     fi 
} 

正如你所看到的,它比你打算做什么稍微复杂, 但并不多。你的建议不起作用的原因是没有分隔符就会进行部分匹配。

所以如果我的路径是/usr/local/sbin:/usr/local/bin,echo ${PATH} | grep /usr/local将返回true,即使/ usr/local不在我的路径中。所以你需要匹配分隔符。但是,如果你grep为:/usr/local:,你也会失败,因为你不会匹配路径中的第一个或最后一个项目,因为$ PATH既不以分隔符开始也不以分隔符结束。这就是使用egrep的原因。 (^ | :)匹配冒号或行的开头。 ($ | :)匹配冒号或行尾。

+1

@Ori,这个答案现在已经过时了。在CentOS 6中,`/ etc/profile`中的`pathmunge`不使用`grep`或`egrep`。 – 2013-12-19 22:26:44

1

我建议进化到pathmunge,我现在用了2年。

pathmunge() { 
if [ -d "$1" ]; then 
    realpath/2>&1 >/dev/null && path=$(realpath "$1") || path="$1" 
    # 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 || { 
    [ "$2" == "after" ] && export PATH="$PATH:$path" || export PATH="$path:$PATH" 
    } 
fi 
} 

1)它检查目录的有效性,对于一个最小性能成本

2)它使用真实路径,以及,命令真实路径被测试为好。将它添加到$ PATH

3)的egrep -q的真实路径之前,你的路是在SunOS 5.6不可用(是的,它仍然是在使用的许多公司)