我正在编写一个脚本来解决我经常遇到的问题。
问题之一是路径中缺少
/sbin
。但情况并非总是如此,所以不要像这样不加区别地将其添加到 .profile
、.bash_profile
、.bashrc
等:
echo "export PATH=\"$PATH:/sbin\"" >> ~/.bashrc
..随着时间的推移,最终会出现多个
export PATH
,最后还有:/sbin:/sbin:/sbin:/sbin:/sbin
......好吧,你明白了。我该如何处理这个问题?
这是一种方法:
echo '[[ ":$PATH:" == *:/sbin:* ]] || PATH="$PATH:/sbin"' >> ~/.bashrc
(顺便说一句,请注意,在更新已经是环境变量的内容时,您不需要
export
。)
工作原理:
[[ expression ]]
,特别是 ==
,请参阅 the Bash Reference Manual, § 3.2.4.2 “Conditional Constructs”。
[[ ":$PATH:" == *:/sbin:* ]]
是一个命令,如果 :$PATH:
包含 :/sbin:
,则返回 0(= 成功),否则返回 1(= 不成功)。command1 || command2
,请参阅 Bash 参考手册,第 3.2.3 节“命令列表”。
[[ ":$PATH:" == *:/sbin:* ]] || PATH="$PATH:/sbin"
是一个运行 PATH="$PATH:/sbin"
除非 :$PATH:
包含 :/sbin:
.pathmunge
函数已在/etc/profile
中定义:
pathmunge () {
case ":${PATH}:" in
*:"$1":*)
;;
*)
if [ "$2" = "after" ] ; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
esac
}
这可能不是“最好”的解决方案,但我对此感到非常满意。我一直喜欢使用 Python 来完成那些在 bash 中需要很长时间才能正确完成的重复性任务,而这绝对符合我的要求。
这个想法是检查
/sbin
是否存在于 $PATH
中,由字符串的开头或结尾或冒号分隔。 grep
甚至扩展测试([[
)可以很容易地为您做到这一点,但对于通用解决方案,其中感兴趣的路径可能具有正则表达式控制字符,或者您必须转义字符串的部分内容。在 Python 中比在 bash 中容易得多:是否可以使用 sed 可靠地转义正则表达式元字符。所以我使用这样的脚本(实际上避免了几乎所有的手动解析):
在路径中
#/usr/bin/env python
"""
Checks if the sole argument is in the PATH.
Returns 0 if yes, 1 if no. It is an error to pass in more
than one command-line argument.
"""
import sys
from is import get_exec_path
from os path import abspath, normcase
if len(sys.argv) != 2:
raise ValueError('Exactly one command line argument must be provided')
path = [normcase(abspath(p)) for p in get_exec_path()]
sys.exit(sys.argv[1] not in path)
这可以用多种语言来实现,比 bash 更简单;我只是碰巧熟悉Python。它应该适用于任何正常的版本,甚至可能是 2.6 之前的版本。它是为在 Unix 或 Windows 上运行而编写的,尽管我猜测它在后者上并不是真正有用。像这样使用它:
if inpath /sbin ; then
echo "export PATH=\"$PATH:/sbin\"" >> ~/.bashrc
fi
或者
inpath /sbin && echo "export PATH=\"$PATH:/sbin\"" >> ~/.bashrc