通过 sudo 运行 nvm(bash 函数)

Yog*_*ogu 4 bash sudo function bash-script

我想编写一个基本上应该运行的初始化脚本

nvm use v0.11.12 && forever start /srv/index.js
Run Code Online (Sandbox Code Playgroud)

作为用户webconfignvm是一个在 in 中声明的 shell 函数~webconfig/.nvm/nvm.sh,它通过source ~/.nvm/nvm.shinwebconfig.bashrc.

我尝试了以下方法:

sudo -H -i -u webconfig nvm

echo "nvm" | sudo -H -i -u webconfig
Run Code Online (Sandbox Code Playgroud)

但他们失败了

-bash:nvm:未找到命令
-bash:第 1 行:nvm:未找到命令

当我在该 shell 中手动运行sudo -H -i -u webconfig并输入时nvm,它可以工作。我究竟做错了什么?

ter*_*don 6

这里的问题,正如经常发生的那样,是关于不同类型的 shell:

  • 当您打开终端模拟器(gnome-terminal例如)时,您正在执行所谓的交互式非登录shell。

  • 当您从命令行登录计算机或运行诸如su username、 或 之类的命令时sudo -u username,您正在运行交互式登录shell。

因此,根据您启动的 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.
Run Code Online (Sandbox Code Playgroud)

换句话说,~/.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. 
Run Code Online (Sandbox Code Playgroud)

所以,你能做的是

  1. 在用户的~/.profileor 中定义函数~/.bash_profile。请记住,~/.profile如果~/.bash_profile存在,将被忽略。还要记住,这~/.bash_profile是特定于bash 的,所以我会使用它.profile,只要确保它~/.bash_profile不存在即可。

  2. 来源~/.nvm/nvm.sh~/.profile