루트가 아닌 경우 스크립트가 실행되는 것을 방지하려면 어떻게 해야 합니까? (그리고 "루트로 실행되지 않습니다! 종료 중..."이 표시됩니다.)

루트가 아닌 경우 스크립트가 실행되는 것을 방지하려면 어떻게 해야 합니까? (그리고 "루트로 실행되지 않습니다! 종료 중..."이 표시됩니다.)

내 출처는 다음과 같습니다.

#!/bin/bash

echo "Running script to free general cached memory!"
echo "";
echo "Script must be run as root!";
echo "";
echo "Clearing swap!";
swapoff -a && swapon -a;
echo "";
echo "Clear inodes and page file!";
echo 1 > /proc/sys/vm/drop_caches;
echo "";

캐시와 기타 항목을 지우고 터미널에서 루트로 실행해야 한다고 말합니다. 기본적으로 스크립트가 루트로 실행되지 않는 것을 감지하면 스크립트 실행이 중지되기를 원합니다.

예:

"Running script to free general cached memory!"
"Warning: script must be run as root or with elevated privileges!"
"Error: script not running as root or with sudo! Exiting..."

높은 권한으로 실행하면 정상적으로 실행됩니다. 어떤 아이디어가 있나요? 감사해요!

답변1

#!/bin/sh

if [ "$(id -u)" -ne 0 ]; then
        echo 'This script must be run by root' >&2
        exit 1
fi

cat <<HEADER
Host:          $(hostname)
Time at start: $(date)

Running cache maintenance...
HEADER

swapoff -a && swapon -a
echo 1 >/proc/sys/vm/drop_caches

cat <<FOOTER
Cache maintenance done.
Time at end:   $(date)
FOOTER

루트 사용자의 UID는 0입니다("루트" 계정 이름에 관계 없음). 반환된 유효 UID가 id -u0이 아닌 경우 사용자는 루트 권한으로 스크립트를 실행하지 않는 것입니다. id -ru실제 ID(사용자의 UID) 테스트 용옮기다스크립트).

$EUID권한이 없는 사용자가 수정할 수 있으므로 스크립트에서 사용 하지 마십시오 .

$ bash -c 'echo $EUID'
1000

$ EUID=0 bash -c 'echo $EUID'
0

사용자가 이렇게 하면 분명히 권한 상승이 발생하지 않지만 스크립트의 명령이 수행해야 하는 작업을 수행하지 않고 파일이 잘못된 소유자로 생성될 수 있습니다.

답변2

당신이 원하는 것은 슈퍼유저 권한이 있는지, 즉 유효 사용자 ID가 0인지 확인하는 것입니다.

zsh다음을 수행할 수 있도록 변수에서 사용 가능 bash하게 만듭니다 .$EUID

if ((EUID != 0)); then
  echo >&2 "Error: script not running as root or with sudo! Exiting..."
  exit 1
fi

POSIX와 유사한 셸의 경우 id표준 명령을 사용할 수 있습니다.

if [ "$(id -u)" -ne 0 ]; then
  echo >&2 "Error: script not running as root or with sudo! Exiting..."
  exit 1
fi

id -un또는 whoami또는 의 모든 $USERNAME변수는 zsh다음을 제공합니다.첫 번째uid의 사용자 이름입니다. 다른 사용자의 ID가 0인 시스템에서는 root해당 프로세스가 인증된 프로세스의 하위 프로세스인 경우에도 그렇지 않을 수 있습니다 root.

$USER회의대개인증된 사용자를 제공하지만 이에 의존하는 것은 꽤 취약합니다. 이는 쉘에 의해 설정되지 않지만 일반적으로 인증 명령에 의해 설정됩니다(예 login: su(GNU/Linux 시스템에서는 반드시 다른 시스템일 필요는 없음), sudo( sshd적어도 openssh의 명령)...). 그러나 이것이 항상 그런 것은 아니며(uid 변경은 이 변수를 자동으로 설정하지 않으며, uid를 변경하는 애플리케이션에 의해 명시적으로 수행되어야 합니다), 쉘의 조상에 있는 다른 프로세스에 의해 수정되었을 수도 있습니다. $LOGNAME, 동일한 경고는 POSIX(원래 FIPS 151-2)에 의해 지정되므로 더 안정적입니다.

답변3

$USER또는 를 사용하여 whoami현재 사용자를 확인할 수 있습니다.

if [[ "$USER" != "root" ]]; then
    echo "Error: script not running as root or with sudo! Exiting..."
    exit 1
fi

if [[ $(whoami) != "root" ]]; then
    echo "Warning: script must be run as root or with elevated privileges!"
    exit 1
fi

if [[ $(id -u) != "0" ]]; then
    echo "Error: script not running as root or with sudo! Exiting..."
    exit 1
fi

답변4

실제로 원하는 것은 이러한 작업을 수행할 권한이 있는지 확인하는 것입니다. 대신 루트인지 확인하는 것은 나쁜 습관으로 간주됩니다.

루트가 아닌 사용자가 스왑을 수정하고 페이지 캐시를 삭제할 수 있도록 시스템이 구성된 경우 해당 사용자가 스크립트를 실행하면 안 되는 이유는 무엇입니까?

대신 간단히 작업을 시도하고 실패할 경우 유용한 메시지와 함께 종료할 수 있습니다.

if ! ( swapoff -a && swapon -a )
then
  echo "Failed to clear swap (rerun as root?)" >&2
  exit 1
fi

if ! echo 1 > /proc/sys/vm/drop_caches
then 
  echo "Failed to free page cache (rerun as root?)" >&2
  exit 1
fi

관련 정보