이것은 예상대로 작동합니다.
$ sudo -u romain bash -c 'a="b" ; echo $a'
b
$
그런데 -i
변수가 에코되지 않습니다. 왜 그럴까요?
$ sudo -iu romain bash -c 'a="b" ; echo $a'
$
어느 정도 bash 간접 참조 또는 변수 보간이 추가되었는지 궁금합니다 -i
. 그렇다면 이것이 어떻게 작동합니까?
$ sudo -iu romain bash -c 'a="b" ; echo ${a}'
b
$
답변1
-i
with 를 사용하면 sudo
사용자의 로그인 쉘이 사용되며 $SHELL
로그인 쉘로 호출됩니다.
다음과 같이 실행할 명령과 함께 명령을 추가로 제공하는 경우
sudo -u user -i 'some-command'
... 를 sudo
사용하여 명령을 실행합니다 $SHELL -c
. 즉, 인수 목록을 단일 명령줄 문자열로 변환해야 하며 이는 셸에서 다시 평가됩니다. 이렇게 하려면 ( some-command
영숫자, 밑줄, 하이픈 및 달러 기호 제외)의 모든 문자를 이스케이프해야 합니다.
이것은 의미한다
sudo -u user -i bash -c 'a="b" ; echo ${a}'
user 로 실행되며 user
다음과 동일하게 이스케이프됩니다.
$SHELL -c bash\ -c\ \'a\=\"b\"\ \;\ echo\ $\{a\}\'
...사용하면 $a
명령은 다음과 같습니다.
$SHELL -c bash\ -c\ \'a\=\"b\"\ \;\ echo\ $a\'
마지막 명령에서는 $a
시작하기 전에 사용자의 로그인 셸이 확장됩니다 bash -c
. 이전 명령에서 ${a}
사용된 곳은 $\{a\}
유효한 확장이 아니므로 사용자 쉘은 이를 확장하지 않지만 인라인 bash -c
쉘은 이를 보고 ${a}
확장할 수 있습니다.
sudo
이에 대해서는 옵션을 설명하는 매뉴얼 섹션에 설명되어 있습니다 -i
.
-i, --login
Run the shell specified by the target user's password
database entry as a login shell. This means that login-
specific resource files such as .profile, .bash_profile, or
.login will be read by the shell. If a command is specified,
it is passed to the shell as a simple command using the -c
option. The command and any arguments are concatenated,
separated by spaces, after escaping each character (including
white space) with a backslash (‘\’) except for alphanumerics,
underscores, hyphens, and dollar signs. If no command is
specified, an interactive shell is executed. [...]
답변2
이는 sudo가 명령줄에서 얻은 인수를 다른 셸( sudo -i
대상 사용자의 로그인 셸을 실행하지만 일반은 실행하지 않음)에 제공하기 위해 이스케이프하는 방법 sudo
사이의 이상한 상호 작용 때문입니다 .
특히 달러 기호를 남깁니다.$
아니요인용하자면, 그러한 명령은 다음과 같습니다
sudo -i /bin/echo '$USER'
일하다.
그 경우했다또한 달러 기호를 인용하면 작동하지 않지만
sudo -i sh -c 'echo "$USER"'
해야 한다. 글쎄요, 제 말은 그게 효과가 있을 거라고 생각했는데 그게 실행되더라고요둘쉘(대상 사용자의 로그인 쉘 및 sh
우리가 특별히 요청한 것)을 통해 탈출하는 것을 생각하는 것은 고통스럽습니다.
이 $USER
예제는 그다지 유용해 보이지는 않지만 다른 변수와 함께 실행하여 사용자가 로그인 환경에서 얻는 값을 확인하는 것이 좋습니다.
어쨌든 이것은 이 sudo 버그 보고서에 사용된 예제 명령으로, 그 결과 여전히 현재 동작이라고 생각됩니다.
- 버그 564 - sudo가 $를 이스케이프 처리하여 환경 변수에 액세스할 수 없습니다.(bugzilla.sudo.ws)
sudo -i sh -c 'echo $foo'
깨지는 특별한 경우는 여기에서 논의됩니다:
(후자는댓글 링크에같은 문제에 대한 이전 질문)