"-i" 없이 작동하는데 "sudo -i"가 변수 확장을 중단하는 이유는 무엇입니까?

"-i" 없이 작동하는데 "sudo -i"가 변수 확장을 중단하는 이유는 무엇입니까?

이것은 예상대로 작동합니다.

$ 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

-iwith 를 사용하면 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 버그 보고서에 사용된 예제 명령으로, 그 결과 여전히 현재 동작이라고 생각됩니다.

sudo -i sh -c 'echo $foo'깨지는 특별한 경우는 여기에서 논의됩니다:

(후자는댓글 링크같은 문제에 대한 이전 질문)

관련 정보