예시 스크립트는 다음과 같습니다.
#!/bin/bash
sudo su
ls /root
./test.sh
일반 사용자로 사용하면 ls
슈퍼유저로 실행되도록 변경되고 종료되고, 로그아웃하면 ls /root
일반 사용자로 실행됩니다.
누구든지 그 메커니즘에 대해 말해 줄 수 있나요?
답변1
스크립트의 명령은 하나씩 독립적으로 실행됩니다. 스크립트에 있는 모든 명령의 상위 프로세스인 스크립트 자체는 또 다른 독립 프로세스입니다. su 명령은 이를 루트로 변경하지 않으며 변경할 수도 없습니다. su 명령은 루트 권한이 있는 새 프로세스를 생성합니다.
su 명령이 완료된 후에도 여전히 동일한 사용자로 실행 중인 상위 프로세스는 스크립트의 나머지 부분을 실행합니다.
당신이 원하는 것은 래퍼 스크립트를 작성하는 것입니다. 권한 있는 명령은 기본 스크립트로 이동합니다.~/main.sh
#!/bin/sh
ls /root
래퍼 스크립트는 아래와 같이 루트 권한으로 기본 스크립트를 호출합니다.
#!/bin/sh
su -c ~/main.sh root
이 프로세스를 시작하려면 사용자를 루트로 전환한 후 기본 스크립트를 시작하는 래퍼를 실행해야 합니다.
이 패키징 기술을 사용하면 스크립트를 자체 래퍼로 바꿀 수 있습니다. 기본적으로 루트로 실행 중인지 확인하고 그렇지 않은 경우 "su"를 사용하여 재부팅하십시오.
$0은 스크립트 참조 자체를 만드는 편리한 방법이며 whoami 명령은 우리가 누구인지 알려줍니다(우리가 루트입니까?).
따라서 래퍼가 내장된 기본 스크립트는 다음과 같습니다.
#!/bin/sh
[ `whoami` = root ] || exec su -c $0 root
ls /root
exec 사용에 주의하세요. 이는 "이 프로그램을 다음으로 대체"를 의미하며, 실행을 효과적으로 종료하고 최상위에서 루트로 실행되는 su에 의해 시작된 새 프로그램을 시작합니다. 대체 인스턴스는 "루트"이므로 ||의 오른쪽을 실행하지 않습니다.
답변2
스크립트에서 다음을 사용하십시오.
sudo su <<HERE
ls /root
HERE
HERE 블록 사이의 코드는 루트로 실행됩니다.
답변3
추가 인수가 없으면 su
로그인 쉘이 루트에 대해 실행됩니다. 이것이 스크립트의 첫 번째 줄이 실제로 수행하는 작업입니다. 종료하면 로그인 쉘이 닫히고 su가 반환되며 스크립트가 계속 실행됩니다(예: line 2: ) ls /root
. 그냥 sudo ls /root
하고 싶은 대로 하면 될 것 같아요 .
답변4
루트 권한으로 실행하기 위한 스크립트가 필요한 경우 스크립트 시작 부분에 다음을 입력하세요.
if [ ! $(whoami)=”root” ]; then
exec sudo ”$0” ”$@”
echo ”Error: failed to execute sudo” >&2
exit 1
fi
그러면 동일한 매개변수를 사용하여 스크립트가 다시 실행되지만 명령이 성공적으로 시작 sudo
되면 sudo
첫 번째 스크립트 프로세스가 대체되고(때문에 exec
) sudo
ed 버전만 앞으로 이동합니다. 다음 줄이 exec sudo
실행되면 쉘이 시작조차 할 수 없으며 sudo
뭔가 정말 잘못되었음을 의미합니다.
사용자에게 스크립트를 실행할 권한이 있는 경우 sudo
비밀번호를 요청할 수도 있고 요청하지 않을 수도 있습니다. 잘못된 비밀번호를 입력하거나 사용자에게 루트로 스크립트를 실행할 수 있는 권한이 없으면 sudo
표준 오류 메시지가 표시됩니다.
성공하면 sudo
스크립트가 다시 시작되고 이제 루트 권한으로 실행됩니다. if
이제 표현식은 해당 단계를 건너뛰고 나머지 exec sudo...
스크립트를 계속 진행합니다.
따라서 흐름은 다음과 같습니다.
- 상위: 사용자가 스크립트를 실행하는 명령줄 세션
sudo
child: 원래 스크립트를 사용자로 실행했지만 나중에 변경된 쉘 입니다.exec
- Sun Tzu: 루트로 스크립트를 실행하는 쉘입니다.