我正在编写一个 bash 脚本,尝试在 Ubuntu 上自动执行初始设置,但遇到了一个我无法理解的问题。如果我运行以下代码:
sudo apt-get -y update && sudo apt-get -y upgrade
sudo apt-get -y install curl git-core build-essential openssl sqlite3 apache2-prefork-dev mysql-client
git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc
git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
rbenv install -v 1.9.3-p392
....
然后脚本完成,但大多数命令失败,因为rbenv
未定义(在脚本完成后用 进行测试rbenv -v
)。如果我运行source ~/.bashrc
,rbenv
则变为已定义。
但是,如果我运行完全相同的代码,但将其替换source ~/.bashrc
为source /home/username/.bashrc
,则rbenv
定义,并且脚本可以顺利完成。有人可以解释这种差异吗?我认为了解相对路径何时以及为何不起作用将在未来非常有用。
答案1
在初始设置期间,您实际上不需要“$(rbenv init -)”调用。这部分稍后在交互式环境中使用 rbenv 时会有所帮助,并且可能在调试脚本时增加一些不透明度。
尝试在实际的 rbenv 调用之前添加:
export PATH="$HOME/.rbenv/bin:$PATH"
事实上,要在脚本中使用 rbenv,只需将其和 shims 目录添加到路径中就足够了。
至于“source”失败,source 是一种 bashism。如果您假设 bash 是默认 shell 并使用 #!/bin/sh 作为 hashbang,那么 ubuntu 可能会对您耍一些花招(如果我没记错的话,默认为 dash)。
答案2
~
并且$HOME
应该始终引用相同的路径,所以我预计会遗漏其他东西。
可能出现的问题:
- 您使用 运行此脚本吗
sudo
?如果是,$HOME
可能是root
的主页。 - 不是
$HOME
吗/home/username/
?虽然/home/username
是您的主目录的标准路径,但也可以以其他方式配置。尝试echo $HOME
验证一下。
为了更好地了解正在发生的事情:
-
在顶部添加一行
set -ex。 -e 使其在第一次失败时退出,-x 使其在执行时打印正在发生的事情。 - 在顶部添加
echo "$(env)"
以使其打印出环境,或者如果您已经设置了 -x 或 set -ex,只需添加
env