我想要一种在系统范围内或为单个用户将内容添加到 $PATH 的方法,而不必多次添加相同的路径。
想要这样做的原因之一是可以在 中进行添加.bashrc
,这不需要登录,并且在使用 (eg) 的系统上也更有用lightdm
,它从不调用.profile
。
我知道有关的问题如何清除重复项来自 $PATH,但是我不想删除重复项。我想要一种方法仅当路径尚不存在时才添加路径。
答案1
假设我们要添加的新路径是:
new=/opt/bin
然后,使用任何 POSIX shell,我们可以测试是否new
已在路径中,如果不在则添加它:
case ":${PATH:=$new}:" in
*:"$new":*) ;;
*) PATH="$new:$PATH" ;;
esac
请注意冒号的使用。如果没有冒号,我们可能会认为new=/bin
已经在路径中了,因为它的模式与/usr/bin
.虽然 PATH 通常有许多元素,但也会处理 PATH 中零和一个元素的特殊情况。 PATH 最初没有元素(为空)的情况通过使用${PATH:=$new}
它PATH
来处理($new
如果它为空)。以这种方式设置参数默认值是所有 POSIX shell 的一个功能:请参阅 2.6.2 节POSIX 文档.)
可调用函数
为了方便起见,可以将上面的代码放入一个函数中。该函数可以在命令行中定义,或者要使其永久可用,请将其放入 shell 的初始化脚本中(对于 bash 用户,就是这样~/.bashrc
):
pupdate() { case ":${PATH:=$1}:" in *:"$1":*) ;; *) PATH="$1:$PATH" ;; esac; }
要使用此路径更新功能将目录添加到当前 PATH:
pupdate /new/path
答案2
创建一个名为的文件/etc/profile.d
,例如mypath.sh
(或任何你想要的)。如果您使用 lightdm,请确保它是可行的,否则使用/etc/bashrc
或源自相同的文件。添加以下功能:
checkPath () {
case ":$PATH:" in
*":$1:"*) return 1
;;
esac
return 0;
}
# Prepend to $PATH
prependToPath () {
for a; do
checkPath $a
if [ $? -eq 0 ]; then
PATH=$a:$PATH
fi
done
export PATH
}
# Append to $PATH
appendToPath () {
for a; do
checkPath $a
if [ $? -eq 0 ]; then
PATH=$PATH:$a
fi
done
export PATH
}
$PATH 开头(前置)的内容优先于后面的内容,相反,末尾(附加)的内容将被之前的内容取代。这意味着如果您的 $PATH 是/usr/local/bin:/usr/bin
并且两个目录中都有可执行文件,则默认情况下将使用gotcha
中的那个。/usr/local/bin
您现在可以在同一文件、另一个 shell 配置文件或命令行中使用:
appendToPath /some/path /another/path
prependToPath /some/path /yet/another/path
如果它位于 a 中.bashrc
,则当您启动新 shell 时,它将阻止该值多次出现。有一个限制,如果您想附加预先添加的内容(即在 $PATH 内移动路径)或反之亦然,您必须自己执行此操作。
答案3
你可以这样做:
echo $PATH | grep /my/bin >/dev/null || PATH=$PATH:/my/bin
注意:如果您从其他变量构建 PATH,请检查它们是否不为空,因为许多 shell 将“”解释为“。” 。
答案4
~/.profile
多年来我一直在各种文件中携带这个小功能。它存在于/etc/profile
Red Hat Linux 及其衍生品(CentOS、Fedora)中。
pathmunge () {
if ! echo $PATH | /bin/grep -Eq "(^|:)$1($|:)" ; then
if [ "$2" = "after" ] ; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
fi
}
因此,要将新目录添加到以下目录的开头PATH
:
pathmunge /new/path
到最后:
pathmunge /new/path after