스크립트가 루트로 실행 중인지 어떻게 확인할 수 있습니까?


104

간단한 bash 스크립트를 작성하고 있지만 루트로 실행 중인지 여부를 확인해야합니다. 나는 그것을 할 수있는 매우 간단한 방법이 있다는 것을 알고 있지만, 방법을 모른다.

그냥 명확합니다 :
스크립트 작성하는 간단한 방법 무엇 foo.sh은 , 그래서 명령 ./foo.sh출력 0하고 명령 sudo ./foo.sh출력 1?

답변:


148
#!/bin/bash
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 
   exit 1
fi

7
시스템 변수 EUID를 사용하는이 한 가지 원인 (일부 테스트 후)이 명령 (id -u)을 실행하는 것보다 (약 100 배) 빠릅니다.하지만 모든 대답이 훌륭했습니다.
Malabarba

18
또한, $UID$EUIDbashisms입니다. POSIX 호환 쉘에는 해당 변수가 없으므로 id(1)대신 사용해야 합니다.
David Foerster

3
bash 스크립트 에서을 사용할 수 있습니다 if ((EUID)); then. @geirha의 의견
jfs

7
@Andrew : 변수는로 전달되기 전에 대체됩니다 sudo. 당신이 실행 sudo sh -c 'echo $EUID'하면 예상 결과를 볼 수 있습니다.
M. Dudley

6
- 앤드류 늦어서 여기 방법 합니다만, 후대 알 $EUID(@DavidFoerster에 의해 위에서 언급 한 바와 같이)를 Bashism이며, 당신은 /bin/sh가장 가능성에 대한 링크입니다 /bin/dash,하지 /bin/bash. sudo bash -c 'echo $EUID'예상 결과를 산출합니다.
Adrian Günter

118

루트 사용자의 이름은 "root"일 필요는 없습니다. whoami사용자 ID를 가진 첫 번째 사용자 이름을 반환합니다 0. $USER로그인 한 사용자의 이름을 포함하며 사용자 ID는 가질 수 0있지만 이름은 다릅니다.

계정이 루트로 로그인했는지 여부를 확인하는 신뢰할 수있는 유일한 프로그램 :

id -u

내가 사용 -u에 대한 효과가 없는, 사용자 ID -r에 대한 실제 사용자 ID. 권한은 실제 사용자 ID가 아닌 유효 사용자 ID에 의해 결정 됩니다 .

테스트

/etc/passwd0주어진 순서대로 사용자 ID 를 가진 다음 사용자 이름을 포함합니다 .

rootx
root2

로 로그인 root2하면 다음 결과가 나타납니다.

  • whoami: rootx
  • echo $USER: root2(빈 환경에서 프로그램이 시작된 경우 빈 문자열을 반환합니다. 예 env -i sh -c 'echo $USER')
  • id -u: 0 당신이 볼 수 있듯이, 다른 프로그램은이 검사에서 실패하고 id -u통과했습니다.

업데이트 된 스크립트는 다음과 같습니다.

#!/bin/bash
if ! [ $(id -u) = 0 ]; then
   echo "I am not root!"
   exit 1
fi


5
필자는 항상 sh( dash대신)를 인터프리터로 사용하여 가능한 POSIX 호환 상태를 유지하려고합니다 bash. 그러나 좋은 기회, 다른 포크를 저장 :)
Lekensteyn

잠시 추워 진 후, 돌아와서 살펴 보았습니다. Lekensteyn의 방법은 실제로 더 나은 것 같습니다. 그의 대답은 이제 새로 받아 들여진 대답입니다. +1 당신에게 Lekensteyn, esp. 이 질문에서 구하기 힘든 배지를 얻는 것에 대해;)
Thomas Ward

내 질문을 받아들이는 데 오래 기다려 주셔서 감사합니다 : DI는이 답변에 대한 골드 포퓰리스트 배지와 청동 좋은 답변을 받았습니다 :) 나는이 질문이 어떻게 하루에 345 번의 인기를 얻었는지 궁금합니다!
Lekensteyn

3
더 짧은 버전을 보았습니다 [ -w / ]. 아이디어는 동일하게 유지됩니다. 참고 : 특정 chroot에서는 존재 [ -w /etc/shadow ]하지 않기 때문에 실패하므로 /etc/shadow접근 방식 /이 선호됩니다. 더 나은 방법은 루트 권한의 실제 요구를 확인하는 것입니다. 스크립트가에 쓰기가 필요한 /etc/someconfig경우 해당 파일이 쓰기 가능한지 또는 파일이 존재하지 않고 쓰기 가능한지 확인하십시오 /etc.
Lekensteyn

30

으로 @Lekensteyn 말했다 당신은 유효 사용자 ID를 사용해야합니다. id -ubash 를 호출 할 필요가 없습니다 .

#!/bin/bash

if [[ $EUID -ne 0 ]]; then
   echo "You must be root to do this." 1>&2
   exit 100
fi

의견에서 @geirha의 제안은 산술 평가를 사용합니다.

#!/bin/bash

if (( EUID != 0 )); then
   echo "You must be root to do this." 1>&2
   exit 100
fi

7
일반적으로 ((..))숫자 [[..]]를 테스트하고 문자열과 파일을 테스트 하는 데 사용해야 하므로 if (( EUID != 0 )); then대신 또는 그냥if ((EUID)); then
geirha

@geirha : 귀하의 제안을 추가했습니다.
jfs

2
EUID이어야한다 $EUID. 을 사용하는 대신을 (( $EUID != 0 ))사용하십시오 [ $EUID != 0 ]. 작동 dash합니다.
Lekensteyn

2
@ Lekensteyn : EUID잘 작동합니다. 질문에 태그가 bash없습니다 dash. 명령 env -i sh -c '[ $EUID != 0 ]'이 실패했지만 env -i bash -c '(( EUID != 0 ))'작동합니다. btw, dashUbuntu에서 ASCII가 아닌 일부 문자에는 작동하지 않습니다. stackoverflow.com/questions/5160125/… 2011 년이며 다른 언어를 사용하는 사람들이 있습니다.
jfs

지루하고 지루한 동안 이것에 대해 되돌아보고 테스트 한 후, $EUID이 시점부터 물건 과 함께 여기에 나열된이 방법을 사용할 것 입니다. 결과적으로 수락 된 답변을 변경했습니다.
토마스 워드

20

whoami현재 사용자를 리턴하는 명령 을 사용하여이를 수행 할 수 있습니다 .

#!/bin/bash

if [ `whoami` != 'root' ]
  then
    echo "You must be root to do this."
    exit
fi

...

You must be root to do this.현재 사용자가 아닌 경우 위를 실행하면 인쇄 됩니다 root.


참고 : 경우에 따라 다른 방법으로 $USER변수 를 간단히 확인할 수도 있습니다.

if [ $USER != 'root' ]

코드를 살펴보고 스크립트가 실패하지 않는지 확인하십시오. 그것이 작동한다면, 나는 당신의 대답을 받아 들일 것입니다 :)
Thomas Ward

4
@George Edison : $USER특히 이런 식 으로을 사용하지 않는 것이 좋습니다 . $USER로그인 쉘에 의해 설정되며 프로그램 ( env -i sh -c 'echo $USER')으로 전파 될 필요는 없습니다 . 그런 식 $USER으로 비어 있고 구문 오류가 발생합니다.
Lekensteyn

1
@Lekensteyn $USER쉘에 의해 설정 될 뿐만 아니라 스푸핑하기 쉬운 것도 있습니다. Whoami는 실제 사용자를 반환합니다.
Paul de Vrieze 2013 년

2
@PauldeVrieze 그 수표를 속이는 요점은 무엇입니까?
htorque

1
@andrewsomething : $USER쉘에 의해 해석되므로, 예제가 sudo sh -c 'echo $USER'의미가 있어야합니다 . @George : UID 0에 대해 whoami항상 반환 되는 잘못된 가정을 root합니다.
sam hocevar

11

효율성을 고려하여 먼저 EUID환경 변수를 테스트 한 다음 존재하지 않는 경우 표준 id명령을 호출하십시오 .

if ((${EUID:-0} || "$(id -u)")); then
  echo You are not root.
else
  echo Hello, root.
fi

이렇게하면 OR 바로 가기로 인해 메모리 내 변수의 쿼리보다 시스템 명령을 호출하지 않아도됩니다.

코드 재사용 :

function amIRoot() {
  ! ((${EUID:-0} || "$(id -u)"))
}

벤치마킹하지 않은 것이 두렵습니다. 글쎄요 id -u. pastebin.com/srC3LWQy
LinuxSecurityFreak


2

루트로만 스크립트를 실행 가능하게하는 간단한 방법은 다음과 같이 스크립트를 시작하는 것입니다.
#!/bin/su root


1
이러지 마 루트로 직접 로그인을 시도하는 반면 sudo는 금지되어 있기 때문에 많은 시스템에서 sudo가 필요할 수 있습니다. 또한 shebang은 스크립트가 설계된 스크립트에서 스크립트가 실행되도록하는 반면 스크립트를 작성하면 루트의 기본 쉘에서 스크립트가 실행되므로 작성자가 아닌 다른 사람이 스크립트를 실행할 경우 예측할 수 없습니다. 따라서 shebang을 사용하여 스크립트의 권한을 높이면 이식성이 심각하게 손상되어 많은 시스템에서 오류가 발생합니다. (su : 인증 실패)
StarCrashr 2018 년


1

이 스 니펫은 다음과 같습니다.

  • 다른 세션에서 확인
  • 사용 제안 sudo !!
  • 오류를 반환
if [ "$ (whoami & 2> / dev / null)"! = "root"] && [ "$ (id -un & 2> / dev / null)"! = "root"]
      그때
      echo "이 스크립트를 실행하려면 루트 여야합니다!"
      에코 " 'sudo !!'사용"
      1 번 출구
fi

1

이 답변은 아이디어를 저장하기위한 것이며 일부는 도움이 될 수 있습니다. 데스크탑 GUI에서 실행되고 루트 권한이 필요한 스크립트가 필요한 경우 다음과 같이하십시오.

#!/bin/bash
if ! [ $(id -u) = 0 ]; then
   gksudo -w $0 $@
   exit
fi

#here go superuser commands, e.g. (switch intel cpu into powersave mode):
echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
cpupower frequency-set -g powersave

이렇게하면 루트 사용자 암호를 묻는 멋진 대화 상자 창이 나타납니다. 명령 행 sudo와 마찬가지로.

gksudo다음 시스템에서 사용할 수와 함께 설치되지 않을 수 있습니다 sudo apt-get install gksu.


0

이 코드는 EUID를 정의하지 않는 Bash 및 Stock Bourne sh (FreeBSD에서 테스트)에서 작동합니다. EUID가 존재하면 해당 값이 리턴되고, 그렇지 않으면 'id'명령이 실행됩니다. 쉘 내장 ":-"을 사용하므로 위의 "또는"예제보다 약간 짧습니다.

sh의 뿌리 :

# echo $EUID

# euid=${EUID:-`id -u`}
# echo $euid
0

In bash:
[chaapala@tenfwd2 ese]$ euid=${EUID:-`id -u`}
[chaapala@tenfwd2 ese]$ echo $euid
10260
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.