我最近安装了几个软件,需要将它们的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
我以为这很有效...直到我重新启动电脑并在尝试登录时被锁定在我的会话之外。我花了一段时间才弄明白这实际上是因为我的.profile
;一旦我注释掉这些行,我就可以登录到我的会话而不会被反弹。
我的问题是:我写这些代码哪里错了?语法有误吗?还有其他更好的方法吗?发生了什么?
答案1
在里面Ubuntu 12.04 上的默认设置,该.profile
文件由 加载/usr/sbin/lightdm-session
。这是 shell 脚本,由 执行/bin/sh
。
在 Ubuntu 上/bin/sh
,短跑。您已使用过狂欢dash 不支持的功能。Dash 和 Bash 都具有相同的核心功能,但 dash 坚持这些核心功能以实现快速和小巧,而 bash 则以需要更多资源为代价添加了许多功能。通常将 dash 用于不需要额外功能的脚本,而将 bash 用于交互式使用(尽管嘚 有很多更好的功能)。
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
看避免源上的 $PATH 重复如果您想确保不会出现重复的条目。
您可能不想为每个安装的程序将新目录添加到 PATH,而是希望在现有目录中设置符号链接。对于~/.cabal/bin
,您需要将其放在路径中,因为可执行文件会来来去去;不过,我会将其放在 PATH 的末尾,以避免与系统上现有的程序发生潜在冲突。~/bin
在 Ubuntu 上, 已经在 PATH 中。对于您手动安装的程序(例如 vert.x),存放或者克斯托非常适合管理符号链接。请参阅跟踪程序了解 stow 的介绍。
答案2
我认为,对于您而言,使二进制文件可用作命令的最佳做法是将所需内容链接到 /usr/bin。弄乱 $PATH 绝不是好事。
您可以使用“cp”以递归方式创建符号链接,如下所示:
cp -rs $HOME/bin/* /usr/bin #This will link all non hidden files
cp -rs $HOME/bin/.[^.]* /usr/bin # This will link all the hidden files
只需使用与您当前代码相同的逻辑,使其适应您的场景即可。
编辑:如果你将 dotglob 设置为,则可以只使用上述代码的第一行真的在 bash 上。像这样:
shopt -s dotglob #This will make Bash include filenames beginning with a '.' in the results of filename expansion
cp -rs $HOME/bin/* /usr/bin #Now, this will link ALL files in that directory to the destination
编辑 2:正如您在下面的评论中看到的,最好使用 /usr/local/bin 而不是 /usr/bin。阅读评论以了解原因。