다음 Bash 별칭을 생각해 보세요. 금방 생각났지만 더 깊이 파고들 시간이 없었습니다.
alias su='sudo -s'
저는 Bash를 실행하고 있지만 언젠가 공유하기 위해 GitHub에 게시할 수 있으므로 이 솔루션을 이식 가능하게 만들고 싶습니다.
사람들이 겪을 수 있는 문제는 이미 루팅된 상태에서 해당 프로그램(이 별칭)을 실행하는 것입니다.
데모:
$ su
[sudo] password for vlastimil:
# su
# su
#
exit
#
exit
#
exit
$
중첩된 쉘 세션을 방지하는 방법이 있습니까?
중요: 저는 별도의 파일이 아닌 사용자와 루트에 동일한 별칭 파일을 사용합니다. 솔루션은 이식 가능해야 합니다(POSIX).
답변1
su
API, 의미 체계, 동작이 서로 다른 명령 이므로 sudo -s
명령 중 하나를 다른 명령에 별칭으로 지정해서는 안 됩니다.
여기서는 로그인 쉘을 시작하는 명령을 원하는 것처럼 보이지만 root
권한이 없는 쉘에서 호출될 때만 가능하므로 다음과 같은 스크립트를 작성하겠습니다.root
sudo
rootshell
#! /bin/sh -
die() {
printf >&2 '%s\n' "$@"
exit 1
}
[ "$#" -eq 0 ] || die "Usage: $0
Starts a root shell, no argument accepted."
[ "$(id -u)" -eq 0 ] && die "You're already superuser!"
exec sudo -s
시스템 구성의 기본 대상 사용자 가 아닌 경우 명령(또는 시스템의 uid 0 사용자 이름) -u root
에 추가합니다 .sudo
sudo
또는 스크립트를 생성하지 않으려면 rootshell() (<that-code>)
코드를 쉘 rc 파일에 추가하여 코드를 래핑하여 쉘 함수로 만듭니다( $0
모든 쉘이 함수 이름을 에 입력하는 것은 아니므로 함수 이름으로 변경 $0
).
답변2
간단한 솔루션, 쉘 별칭
alias su='[ $(id -u) -ne 0 ] && sudo -s || echo Already root...'
POSIX 호환, 즉 복사하여 붙여넣거나
dash
다른 쉘 지원 별칭을 거의 추측하면 동일한 동작이 발생해야 함을 의미합니다.이것이 바로
EUID
제가 직접적인 가치 비교를 완전히 피하는 이유입니다.
데모:
$ su
[sudo] password for vlastimil:
# su
Already root...
# su
Already root...
#
exit
$
을 사용하는 것을 고려하여 sudo -s
첨부합니다.sudo -s
다른 변형과의 비교.
고급 솔루션, 쉘 스크립트(POSIX)
나는 위의 의사 솔루션(별명)을 오랫동안(수년) 사용해 왔기 때문에 그 단점도 알고 있습니다. 그렇기 때문에 방금 코드 검토에 스크립트를 게시했습니다.스티븐 차제라스, 이것질문그리고 각각의답변거기에서 찾을 수 있습니다. 지금부터 사용할 스크립트를 여기에 배치했습니다.
#!/bin/sh
set -o nounset -o errexit
error()
{
printf >&2 '%s\n' "$@"
exit 1
}
is_root()
{
[ "$(id -u)" -eq 0 ]
}
start_root_shell()
{
exec sudo -s
}
if [ "$#" -gt 0 ]
then
error "Usage of $(basename "$0") script:" \
'' \
'Starts a root shell, no argument accepted.'
fi
if is_root
then
error 'You are already superuser!'
fi
start_root_shell
감사해요스티븐 차제라스나에게 올바른 방향을 알려줬어요!
답변3
이 답변은 파일 편집에 의존하는 두 부분으로 나뉩니다 sudoers
. (귀하의 예제에는 POSIX가 없거나 사용되지 sudo
않았기 때문에 POSIX 준수와 관련하여 이 질문에 어떻게 대답해야 할지 잘 모르겠습니다 bash
. 그러나 솔루션은 이러한 도구를 사용하는 시스템 간에 이식 가능해야 합니다.)
파일에 부울 변수를 설정하면 사용법을 단순화
sudo
하고 별칭 사용을 피할 수 있습니다. 이제 를 사용하여 루트 셸에 액세스할 수 있습니다.shell_noargs
/etc/sudoers
sudo
sudo -s
예를 들어 일부 셸에서는
bash
변수(예:)를 통해 셸 수준을 추적할 수 있습니다$SHLVL
. 이는sudo
전화를 걸거나 간단히 입력하여 추적 할 수 있습니다bash
. 이것을 쉘 프롬프트에 추가하면 현재 가지고 있는 중첩 수준을 결정하는 데 도움이 됩니다.
sudoers
시스템 제공 파일을 편집하는 대신 자체 파일을 만듭니다 .
sudo EDITOR=nano visudo -f /etc/sudoers.d/local
이 줄을 파일에 추가하고 저장하십시오.
# Allow sudo with no args to create a shell
Defaults shell_noargs
# Allow bash to share its nesting level
Defaults env_check+="SHLVL"
의 경우 bash
귀하 ~/.bashrc
(아마도 ~/.bash_profile
또는 ~/.profile
)로 이동하여 정의된 행을 찾으세요 PS1
. 를 포함하도록 수정하세요 $SHLVL
. 예를 들어 내 Debian 시스템에서는 다음과 같이 설정되어 있습니다.
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\W\$ '
다음과 같은 내용을 포함하도록 수정하겠습니다 $SHLVL
.
PS1='${debian_chroot:+($debian_chroot)}\u@\h[$SHLVL]:\W\$ '
마지막으로 루트 구성 파일 편집을 반복합니다.
사용 중인 쉘이 bash
이 기능을 제공하지 않는 경우 $SHLVL
구현하는 것이 쉽지 않습니다 .만약에쉘은 시작될 때마다 구성 파일을 실행합니다. ( sh
불행히도 POSIX는 그렇지 않습니다.)