我的 `.profile` 有问题

我的 `.profile` 有问题

我最近安装了几个软件,需要将它们的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。阅读评论以了解原因。

相关内容