我想编写一个基本上应该运行的初始化脚本
nvm use v0.11.12 && forever start /srv/index.js
作为用户webconfig
。nvm
是在 中声明的 shell 函数,通过in 's~webconfig/.nvm/nvm.sh
包含该函数。source ~/.nvm/nvm.sh
webconfig
.bashrc
我尝试了以下方法:
sudo -H -i -u webconfig nvm
echo "nvm" | sudo -H -i -u webconfig
但他们失败了
-bash:nvm:未找到命令
-bash:第 1 行:nvm:未找到命令
当我在该 shell 中手动运行sudo -H -i -u webconfig
并输入时,它可以工作。nvm
我究竟做错了什么?
答案1
正如经常出现的情况一样,这里的问题与不同类型的 shell 有关:
当您打开终端仿真器(
gnome-terminal
例如)时,您正在执行所谓的交互式、非登录壳。当您从命令行登录计算机或运行诸如
su username
、 或 之类的命令时sudo -u username
,您正在运行交互式登录壳。
因此,根据您启动的 shell 类型,将读取一组不同的启动文件。从man bash
:
When bash is invoked as an interactive login shell, or as a non-inter‐
active shell with the --login option, it first reads and executes com‐
mands from the file /etc/profile, if that file exists. After reading
that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile,
in that order, and reads and executes commands from the first one that
exists and is readable. The --noprofile option may be used when the
shell is started to inhibit this behavior.
换句话说,~/.bashrc
被登录 shell 忽略。由于您使用的是-i
选项sudo
,因此正在读取用户登录 shell 的启动文件(从man sudo
):
-i, --login
Run the shell specified by the target user's password data‐
base entry as a login shell. This means that login-specific
resource files such as .profile or .login will be read by the
shell.
所以,你能做的是
在用户的
~/.profile
或~/.bash_profile
中定义该函数。请记住,~/.profile
如果~/.bash_profile
存在,则会被忽略。另请记住,这~/.bash_profile
是特定于 bash 的,因此我将使用.profile
它,只需确保它~/.bash_profile
不存在即可。来源
~/.nvm/nvm.sh
自~/.profile
.
答案2
@特登已经对此添加了一些详细信息,因此我不再重复。重申一下,问题的原因很可能是bash
作为登录 shell 调用时出现的有些奇怪的行为,因为它不会自动获取 ,.bashrc
而是仅查找~/.bash_profile
、~/.bash_login
或~/.profile
。
通常的做法是将代码添加到这些配置文件之一以获取.bashrc
.默认情况下,我有以下代码~/.profile
:
if [ "$BASH" ]; then
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
fi
更新
从下面的评论来看,我认为最好的解决方案可能是从[ -z "$PS1" ] && return
中删除该行.bashrc
并保留其他所有内容不变。
答案3
sudo -Hu webconfig bash -c '. ~/.nvm/nvm.sh && nvm'