루트가 아닌 스크립트 실행을 중지하는 방법 (및“루트로 실행되지 않음! 종료 중…”)


17

내 소스는 다음과 같습니다.

#!/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..."

상승 된 권한으로 실행하면 정상적으로 실행됩니다. 어떤 아이디어? 감사!



2
@muru, 다른 질문은 반대입니다. 루트로 실행하는 경우 스크립트를 실패하십시오.
Stéphane Chazelas

3
@ StéphaneChazelas 아, 내 나쁜. 취소
muru

다른 방법은 root접두사 앞에 root와 같이 실행해야하는 모든 명령을 접두어 로 수행하여 수행되는 작업량을 제한하는 것 입니다 sudo.
reinierpost

답변:


46
#!/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 -u가 0이 아닌 경우 사용자는 루트 권한으로 스크립트를 실행하지 않은 것입니다. id -ru실제 ID ( 스크립트 를 호출 하는 사용자의 UID)를 테스트하는 데 사용 합니다 .

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

$ bash -c 'echo $EUID'
1000

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

사용자가이 작업을 수행 한 경우 분명히 권한 상승으로 이어지지는 않지만 스크립트의 명령이 수행해야 할 작업을 수행하지 못하고 파일을 잘못된 소유자 등으로 만들 수 있습니다.


1
참고 : 솔라리스 5.10에 /bin/id -u제공/bin/id: illegal option -- u Usage: id [-ap] [user]
모니카 jrw32982 지원

1
@ jrw32982 Solaris에서 POSIX 유틸리티에 액세스하려면 /usr/xpg4/bin일찍 해야합니다 $PATH.
Kusalananda

1
요점은 -u옵션이 id보편적이지 않기 때문에이 솔루션은 POSIX 버전이 idPATH에서 먼저 발생해야 한다는 경고에 대해서만 보편적 입니다.
jrw32982는 Monica

1
스크립트가 Solaris에서 올바른 POSIX 유틸리티를 선택하려면 @ jrw32982 수정, $PATH즉 있도록 스크립트의 상단에 /usr/xpg4/bin전입니다 /bin. 비 POSIX 사용을 주장한다면 id분명히 더 휴대용 솔루션을 만들어야합니다.
Kusalananda

1
@Harry 예. 스크립트가 PATH=$( getconf PATH )다른 명시 적 기본 경로를 사용 하거나 설정 하거나을 호출하기위한 명시 적 경로를 사용할 수 있습니다 id.
Kusalananda

19

나는 당신이 원하는 것이 슈퍼 사용자 권한이 있는지, 즉 유효 사용자 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, suGNU / 리눅스 시스템, 반드시 다른 사람)에 ( sudo, sshd적어도 OpenSSH를에서 (것) ...). 항상 그렇지는 않지만 (uid를 변경해도 해당 변수가 자동으로 설정되지는 않으며 uid를 변경하는 응용 프로그램에서 명시 적으로 수행해야 함) 쉘의 조상의 다른 프로세스에 의해 수정되었을 수도 있습니다. $LOGNAMEPOSIX (원래 FIPS 151-2)에서 지정한 것과 동일한 경고가 더 안정적입니다.


12

당신은 사용할 수 있습니다 $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

1
NP. 말 그대로 bash 매뉴얼 [ gnu.org/software/bash/manual/bashref.html]을 직접 읽는 것이 좋습니다 . 실제로 놀랍도록 쉬운 준비입니다. 이 답변에 대해서는 특히 다음을 참조하는 것이 좋습니다. 3.2.4.2 Conditional Constructs 3.5.4 Command Substitution
Jesse_b

9
옵션이 id -u있거나없는 명령 -n은 whoami를 사용하는 대안입니다. -n없이 0과 비교하는 것은 커널이 실제로 수행하는 테스트와 더 잘 일치합니다. 모든 커널은 암호 파일의 이름이 아니라 ID입니다.
이카루스

6
나는 사용 $(id -u)이 더 좋다고 생각합니다 . 일부 (악의적 인) 경우에는 $USER잘못되었을 수 있습니다.
Basile Starynkevitch

1
@Jesse_b에서 제공하는 링크에 관심이있는 사람들에게는 오타가 있습니다. gnu.org/software/bash/manual/bashref.html
Kryten

1
일부 시스템은 "root"를 uid 0을 가진 권한있는 계정의 이름으로 사용하지 않습니다. QNAP은 하나의 이름으로 떠 오릅니다. 따라서 루트 계정 이름이 아닌 uid 0 만 확인해야합니다.
roaima

10

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

루트가 아닌 사용자가 스왑 및 드롭 페이지 캐시를 수정할 수 있도록 시스템을 구성한 경우 해당 사용자가 스크립트를 실행하지 않아야하는 이유는 무엇입니까?

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

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

루트가 아닌 사용자가 스왑을 해제 하시겠습니까?
Kusalananda

2
예. SELinux로이를 설정할 수 있습니다. 마찬가지로 루트 프로세스에서이를 수행하지 못하게 할 수 있습니다.
다른 사람

1
exit사용자가 현재 권한으로 최대한 많은 것을 원할 경우에 실패한 후 원하지 않을 수 있습니다 . (그러나이 모든 것이 루트를 필요로하는 일반적인 시스템의 경우, 종료가 더 유용하고 덜 시끄 럽습니다.)
Peter Cordes

2
나는 당신이 루트인지 아닌지를 확인하는 것이 "나쁜 습관"이라고 말하지 않을 것입니다. 특히 정확히 알고 싶은 것이 있다면 . 귀하가 원하는 것을 할 수있는 충분한 권한이 있는지 확인하는 것이 가장 좋습니다.
Erik Bennett
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.