Вопрос или проблема
Когда я запускаю which node
, команда работает, но если я запускаю su - username -s /bin/bash -c 'which node'
, она возвращает пустое значение. Я перепробовал всё, что только можно, и не могу заставить её работать.
Я даже попробовал su - username -s /bin/bash -c 'source ~/.bashrc ; which node'
root@vps-151c25b9:~# which node
/root/.nvm/versions/node/v20.18.0/bin/node
root@vps-151c25b9:~# su - username -s /bin/bash -c 'which node'
root@vps-151c25b9:~#
root@vps-151c25b9:~# su - username -s /bin/bash
username@vps-151c25b9:~$ which node
/home/username/.nvm/versions/node/v20.18.0/bin/node
username@vps-151c25b9:~$
Что я делаю не так? Почему node не отображается при запуске с помощью su?
Правка: Я только что заметил, что когда я запускаю
su - username -s /bin/bash -c "echo $PATH"
Я получаю путь root
, а не пользователя username
. Хотя root
также имеет nvm
и node
, и он тоже их не находит.
Правка 2: Я попробовал одинарные кавычки, чтобы не происходила подстановка $PATH
, и получил свой правильный путь, включая директорию nvm:
su username -c 'echo $PATH'
но когда я пытаюсь
su username -c 'source ~/.bashrc ; which node'
он всё равно пустой.
Правка 3: Я попробовал
su username -c '. ~/.profile ; which which'
(лол) и это вернуло /usr/bin/which
, так что команда работает, просто не для node.
Ответ: Я запустил следующее, и это сработало! Мне пришлось загрузить NVM вручную.
root@vps-151c25b9:~# su - username -c 'export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" ; [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" ; which node'
/home/username/.nvm/versions/node/v20.18.0/bin/node
Спасибо всем за помощь 🙂
Ответ или решение
Чтобы понять, почему команда which node
не возвращает путь к исполняемому файлу Node.js при выполнении в контексте другого пользователя с помощью команды su
, необходимо рассмотреть несколько аспектов работы оболочки и механизмов, связанных с nvm
(Node Version Manager).
1. Контекст выполнения команды
При использовании команды su - username -s /bin/bash -c '...'
, вы создаете новый сеанс оболочки Bash от имени пользователя username
. Этот сеанс загружает стандартные файлы конфигурации окружения, такие как ~/.bashrc
, только в случае, если они явно указаны для загрузки. Если nvm
установлен с использованием ~/.nvm
, его инициализация может не произойти автоматически.
2. Переменные окружения и PATH
Ваши наблюдения о выводе echo $PATH
при использовании su
подтверждают, что новое окружение не включает путь к исполняемым файлам, связанным с nvm
. nvm
управляет версиями Node.js и устанавливает исполняемые файлы в специальную папку в домашнем каталоге пользователя. Поскольку переменная $PATH
не обновляется при простом вызове su
, команда which node
возвращает пустой результат.
3. Инициализация nvm
Чтобы решить эту проблему, необходимо убедиться, что сценарий инициализации nvm
выполнен перед вызовом команды which node
. Вы правильно указали на необходимость загрузки конфигураций с помощью source ~/.bashrc
, но дело в том, что просто выполнение этой команды в одной строке может не инициализировать nvm
должным образом, так как процесс может завершаться до выполнения всех необходимых команд.
4. Правильное выполнение команды
Ваш окончательный успешный пример:
su - username -c 'export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" ; [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" ; which node'
включает в себя следующие важные этапы:
- Установка переменной окружения
NVM_DIR
: Это позволяет программеnvm
понять, где находятся установленные версии Node.js. - Инициализация
nvm
: Проверка существования файлаnvm.sh
и его загрузка. - Вызов
which node
: Теперь команда работает, так какnvm
завершила инициализацию и добавила корректные пути вPATH
.
Заключение
Таким образом, проблема возникает из-за отсутствия правильной инициализации окружения и nvm
при вызове команды через su
. Следовательно, включение инициализации nvm
вручную позволяет решить проблему, что вы и сделали. Важно всегда учитывать, что при переходе между пользователями контекст выполнения и конфигурации окружения могут значительно изменяться, что требует внимательного подхода к инициализации необходимых инструментов и окружений.