Jon*_*n H 4 bash .profile environment-variables
我最近安装了一些软件,需要将它们的bin/
目录添加到我的PATH
. 目前没有任何异常。但是我决定聪明点,并重写了我的一部分,.profile
这样我就不必一遍又一遍地复制/粘贴相同的几行代码。这是我的想法:
# Create an array with directories to be added to PATH
declare -a addpath=("$HOME/bin" "$HOME/.cabal/bin" "/opt/vert.x/current/bin")
# Add directories recursively
for dir in "${addpath[@]}"; do
if [ -d "$dir" ]; then
PATH="$dir:$PATH"
fi
done
Run Code Online (Sandbox Code Playgroud)
我认为这很有效......直到我重新启动我的电脑并在尝试登录时被锁定在我的会话之外。我花了一段时间才弄清楚这实际上是因为我的.profile
; 一旦我将这些行注释掉,我就可以登录我的会话而不会被退回。
我的问题是;这些行我做错了什么?是否有语法错误?有没有其他/更好的方法来做到这一点?发生了什么?
在Ubuntu 12.04的默认设置中,.profile
文件由/usr/sbin/lightdm-session
. 这是 shell 脚本,由/bin/sh
.
在 Ubuntu 上,/bin/sh
是dash。您使用了 dash 不支持的bash功能。Dash 和 Bash 都具有相同的核心功能,但 dash 坚持这些核心功能是为了快速和小巧,而 bash 以需要更多资源为代价增加了很多功能。通常将 dash 用于不需要额外功能的脚本,将 bash 用于交互式使用(尽管zsh 有很多更好的功能)。
Dash 没有数组,也没有declare
内置的,所以它在这条线上轰炸。您可以将路径列表内联:
for dir in "$HOME/bin" "$HOME/.cabal/bin" "/opt/vert.x/current/bin"; do
if [ -d "$dir" ]; then
PATH="$dir:$PATH"
fi
done
Run Code Online (Sandbox Code Playgroud)
如果您想确保不以重复条目结束,请参阅在源代码中将重复项排除在 $PATH 之外。
您可能希望在现有目录中设置符号链接,而不是为您安装的每个程序向 PATH 添加新目录。对于~/.cabal/bin
,您会希望将它放在您的路径中,因为那里的可执行文件会来来去去;不过,我会将它放在 PATH 的末尾,以避免与您系统上的现有程序发生潜在冲突。~/bin
已经在 Ubuntu 上的 PATH 中。对于手动安装的程序,例如 vert.x,stow或xstow非常适合管理符号链接。有关stow 的介绍,请参阅跟踪程序。