쉘 스크립트에서 "sudo su"가 나머지 스크립트를 루트로 실행하지 않는 이유는 무엇입니까?

쉘 스크립트에서 "sudo su"가 나머지 스크립트를 루트로 실행하지 않는 이유는 무엇입니까?

예시 스크립트는 다음과 같습니다.

#!/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) sudoed 버전만 앞으로 이동합니다. 다음 줄이 exec sudo실행되면 쉘이 시작조차 할 수 없으며 sudo뭔가 정말 잘못되었음을 의미합니다.

사용자에게 스크립트를 실행할 권한이 있는 경우 sudo비밀번호를 요청할 수도 있고 요청하지 않을 수도 있습니다. 잘못된 비밀번호를 입력하거나 사용자에게 루트로 스크립트를 실행할 수 있는 권한이 없으면 sudo표준 오류 메시지가 표시됩니다.

성공하면 sudo스크립트가 다시 시작되고 이제 루트 권한으로 실행됩니다. if이제 표현식은 해당 단계를 건너뛰고 나머지 exec sudo...스크립트를 계속 진행합니다.

따라서 흐름은 다음과 같습니다.

  • 상위: 사용자가 스크립트를 실행하는 명령줄 세션
  • sudochild: 원래 스크립트를 사용자로 실행했지만 나중에 변경된 쉘 입니다.exec
  • Sun Tzu: 루트로 스크립트를 실행하는 쉘입니다.

관련 정보