su -c를 사용할 때 어떤 파일이 소스로 제공되나요?

su -c를 사용할 때 어떤 파일이 소스로 제공되나요?

문맥

Ubuntu LTS 14.04에서 작업 중입니다. 루트 사용자로 로그인되어 있습니다. 다음 명령을 실행합니다.

exec su simple_user -c "/bin/bash /etc/init.d/simple_user_service"

따라서 "simple_user_service"는 루트 권한이 아닌 "simple_user" 권한으로 시작됩니다.

질문

"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.

전체 대화형 논리를 로드할 필요 없이 "su simple_user -c"를 사용할 때마다 특정 명령을 실행하는 파일에 BASH_ENV를 설정할 수 있다는 점은 정말 흥미롭습니다.

따라서 실행하기 전에 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는 루트 권한으로 실행해야 하고 rvm은 .bashrc/.profile 파일에만 로드되므로 스크립트에서 rvm 환경을 올바르게 로드할 수 있는 방법이 필요했습니다. 간단히 스크립트에 rvm load 명령을 추가할 수 있었지만 그렇게 하면 내 스크립트가 환경에 따라 달라져서 허용되지 않았습니다.

그래서 권한이 삭제되기 전에 스크립트에 다음을 추가했습니다.

if [ -e "config/BASH_ENV" ]; then
  export BASH_ENV=$(cat config/BASH_ENV)
fi

덕분에 config/BASH_ENV 파일에 설정한 파일에 rvm을 로드할 수 있습니다. 예를 들어 다음과 같을 수 있습니다.

# 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. 또한 우분투 소스 ~/.bashrc~/.profile.

더 많은 아이디어를 얻으려면 INVOCATION섹션을 확인하세요 .man bash

관련 정보