Какие файлы берутся при использовании su -c?

Какие файлы берутся при использовании su -c?

Контекст

Вы работаете на 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чтобы получить больше информации.

Связанный контент