
Контекст
Вы работаете на Ubuntu LTS 14.04. Вы вошли в систему как пользователь root. Вы запускаете следующую команду:
exec su simple_user -c "/bin/bash /etc/init.d/simple_user_service"
Таким образом, «simple_user_service» запускается с привилегиями «simple_user», а не с привилегиями root.
Вопрос
Похоже, что "exec su simple_user -c" не использует .bashrc, .profile или любой другой нормально используемый файл для нового интерактивного терминала оболочки. Я подтвердил это, добавив эту строку в файл simple_user .bashrc:
export TEST="Hello"
Затем в моем скрипте инициализации "simple_user_service":
#!/bin/bash
### BEGIN INIT INFO
# Provides: test_script
# X-Interactive: true
# Short-Description: Test script
### END INIT INFO
echo $TEST
При выполнении скрипта ничего не печатается, но если выполнить следующие команды:
su simple_user
echo $TEST
> Hello
Переменная TEST установлена и распечатана правильно.
Поэтому мне стало интересно: команда "exec su simple_user -c" использует какие-либо файлы профиля simple_user/bashrc? Если да, то есть ли способ узнать, какие именно?
Большое спасибо за вашу помощь!
[Изменить - 2 часа спустя]
Благодаря полученному ответу я более точно понял инструкции 'man bash'. Я нашел это:
When bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and
uses the expanded value as the name of a file to read and execute. Bash behaves as if the following command were executed:
if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
but the value of the PATH variable is not used to search for the file name.
Это действительно интересно, поскольку вы можете задать BASH_ENV для файла, который будет запускать определенные команды каждый раз, когда вы используете «su simple_user -c», без необходимости загружать всю интерактивную логику.
Итак, перед выполнением su simple_user -c
вы можете просто сделать:
export BASH_ENV=~/.bash_script
И задайте в файле simple_user .bash_script следующее:
export TEST="Hello"
Затем, когда я запускаю скрипт «simple_user_service», «Hello» выводится правильно.
Это было действительно полезно для меня, так как мне это было нужно для загрузки всей среды «rvm» (ruby) для запуска определенного скрипта.
Хотите знать больше?
Зачем все эти проблемы?
Потому что я установил Ruby God:http://godrb.com/для мониторинга этого конкретного сценария (отложенное задание).
И я использую «rvm» для управления различными рубинами.
И скрипт автоматически снижает привилегии при необходимости, выполняяexec su application_user -c "/bin/bash application_script"
Поскольку god должен работать с привилегиями root, а rvm загружается только в файлы .bashrc/.profile, мне нужен был способ правильно загрузить среду rvm в моем скрипте. Я мог бы просто добавить команду загрузки rvm в скрипт, но тогда мой скрипт стал бы зависимым от среды, а это было бы неприемлемо.
Поэтому я добавил это в свой скрипт перед тем, как будут отменены привилегии:
if [ -e "config/BASH_ENV" ]; then
export BASH_ENV=$(cat config/BASH_ENV)
fi
Благодаря этому я могу загрузить rvm в файл, который я установил в файле config/BASH_ENV. Например, это может быть:
# In config/BASH_ENV file of your rails app:
export BASH_ENV="~/.bash_script"
# In /home/simple_user/.bash_script
[[ -s "/etc/profile.d/rvm.sh" ]] && . "/etc/profile.d/rvm.sh" # Load RVM function
Тогда мой сценарий и Бог работают так, как и ожидалось.
Я не стал объяснять все эти вещи до получения ответов, чтобы читатели могли сосредоточиться на реальном вопросе.
Но поскольку я получил хороший ответ и благодаря этому нашел хорошее решение, я написал эту правку, чтобы она могла быть полезна другим.
Еще раз спасибо!
решение1
Когда вы это делаете:
su some_user -c 'some_command'
Будет some_command
выполнено как:
bash -c 'some_command'
Предположим bash
, что some_user
оболочка определена в /etc/passwd
.
Теперь, когда вы это делаете, bash -c 'some_command'
вы, по сути, порождаетенеинтерактивный(и конечно жене-логин) сеанс bash
. Поскольку в неинтерактивном режиме оболочка не получает доступ ни к одному файлу, то, как и ожидалось, файл не считывается.
Обратите внимание, что ~/.profile
источник находится в сеансе интерактивного входа bash
и ~/.bashrc
источник находится в сеансе интерактивного входа без входа bash
. Также обратите внимание, что Ubuntu источник находится ~/.bashrc
в ~/.profile
.
Проверьте INVOCATION
раздел, man bash
чтобы получить больше информации.