programing

bash 스크립트에서 루트로 실행 중인지 확인하는 방법

goodsources 2023. 4. 21. 20:49
반응형

bash 스크립트에서 루트로 실행 중인지 확인하는 방법

루트 레벨의 권한이 필요한 스크립트를 작성하고 있는데, 이 스크립트가 루트로 실행되지 않으면 단순히 "루트로 실행해 주세요"라는 에코가 울리고 종료되도록 하고 싶습니다.

다음은 제가 찾는 의사 코드입니다.

if (whoami != root)
  then echo "Please run as root"

  else (do stuff)
fi

exit

어떻게 하면 (깨끗하고 안전하게) 이 작업을 수행할 수 있을까요?감사합니다!

아, 확실히 하자면 (do stop) 부분에는 root이 필요한 명령어 실행이 포함됩니다.따라서 일반 사용자로 실행하면 오류가 발생합니다.이것은 단순히 root 명령어가 필요한 스크립트를 깔끔하게 실행하기 위한 것입니다.스크립트 내에서 sudo를 사용하지 않고 구문설탕을 찾고 있습니다.

$EUID 환경변수는 현재 사용자의 UID를 유지합니다.루트의 UID는 0입니다.스크립트에서 다음과 같은 것을 사용합니다.

if [ "$EUID" -ne 0 ]
  then echo "Please run as root"
  exit
fi

주의: 다음과 같은 경우2: [: Illegal number: 있는지 #!/bin/sh을 at at at at at at at at at at at at at at at at at로 .#!/bin/bash.

몇 가지 답변이 제공되었지만 가장 좋은 방법은 다음과 같습니다.

  • id -u
  • root로 실행되면는 ID 0을 반환합니다.

신뢰성이 , 되는 것 .sudo

bash 스크립트에서는 실행 중인 사용자가 root인지 확인할 수 있는 몇 가지 방법이 있습니다.

경고로서 사용자가 root인지 아닌지를 체크하기 위해root ID가 0인 것.root이것은 매우 강력한 관습으로 널리 받아들여지고 있지만, 누구나 슈퍼 유저의 이름을 바꿀 수 있습니다.

bash를 사용할 때 사용하는 가장 좋은 방법은$EUID , man 이이: :

EUID   Expands to the effective user ID of the current  user,  initialized
       at shell startup.  This variable is readonly.

이 더 낫다, 라고 하는 것보다 .$UID변경할 수 있으며 스크립트를 실행하고 있는 실제 사용자를 반영하지 않습니다.

if (( $EUID != 0 )); then
    echo "Please run as root"
    exit
fi

으로는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★sudorootroot로 실행되지 때 합니다.하다

SUDO=''
if (( $EUID != 0 )); then
    SUDO='sudo'
fi
$SUDO a_command

할 때 하거나 슈퍼유저를 사용할 때 루트별로 명령어를 실행할 수 있습니다.sudo★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

되어야 하는 에 따라 합니다(루트).0500를 참조해 주세요.

나의 원라이너:

if [ "$(id -u)" -ne 0 ]; then echo "Please run as root." >&2; exit 1; fi

이 답변에서 명확하게 하자면, 독자는 와 같은 현대의 셸과 와 같은 휴대용 POSIX 셸의 차이를 이해할 수 있을 것이다.

투표율이 높은 답변들이 많은 부분을 잘 설명해 주기 때문에 나는 여기에 설명할 것이 많지 않다고 생각한다.

하지만 더 설명할 것이 있다면 주저하지 말고 말씀해주세요.그 공백을 메우면서 최선을 다하겠습니다.


퍼포먼스와 신뢰성을 위해 최적화된 All-Round 솔루션, 모든 쉘

새로운 솔루션:

# bool function to test if the user is root or not
is_user_root () { [ "${EUID:-$(id -u)}" -eq 0 ]; }

파일에 (「 」(「 」)is_user_root__benchmark)

#+------------------------------------------------------------------------------+
#|                           is_user_root() benchmark                           |
#|                  "Bash is fast while Dash is slow in this"                   |
#|                          Language: POSIX shell script                        |
#|                     Copyright: 2020-2021 Vlastimil Burian                    |
#|                      M@il: info[..]vlastimilburian[..]cz                     |
#|                               License: GPL 3.0                               |
#|                                 Version: 1.2                                 |
#+------------------------------------------------------------------------------+

readonly iterations=10000

# intentionally, the file does not have an executable bit, nor it has a shebang
# to use it, just call the file directly with your shell interpreter like:

# bash is_user_root__benchmark    ## should take a fraction of one second
# dash is_user_root__benchmark    ## could take around 10 seconds

is_user_root () { [ "${EUID:-$(id -u)}" -eq 0 ]; }

print_time   () { date +"%T.%2N"; }
print_start  () { printf '%s' 'Start  : '; print_time; }
print_finish () { printf '%s' 'Finish : '; print_time; }

printf '%s\n' '___is_user_root()___'; print_start
                   
i=1; while [ "$i" -lt "$iterations" ]; do
    is_user_root
    i=$((i+1))
done; print_finish

사용 예 및 지속 시간:

$ dash is_user_root__benchmark 
___is_user_root()___
Start  : 03:14:04.81
Finish : 03:14:13.29

$ bash is_user_root__benchmark 
___is_user_root()___
Start  : 03:16:22.90
Finish : 03:16:23.08

설명.

가 몇 배 $EUID표준 변수, 유효 사용자 ID 번호 실행보다id -u이 솔루션은 POSIX-ly 사용자 ID를 찾기 위한 명령어로, 두 가지 기능을 모두 적절하게 조합합니다.만약, 그리고 만약의 경우$EUID는 어떤 로든 사용할 수 없는 입니다.id -u명령어가 실행되어 상황에 관계없이 적절한 반환값을 얻을 수 있습니다.


OP에서 몇 년 만에 이 솔루션을 게시하는 이유

음, 내가 제대로 봤다면 위에 빠진 코드가 있는 것 같아.

고려해야 할 변수가 많습니다.그 중 하나가 퍼포먼스와 신뢰성을 조합하는 것입니다.


휴대용 순수 POSIX 솔루션 + 위 기능의 사용 예

#!/bin/sh

# bool function to test if the user is root or not (POSIX only)
is_user_root ()
{
    [ "$(id -u)" -eq 0 ]
}

if is_user_root; then
    echo 'You are the almighty root!'
    # You can do whatever you need...
else
    echo 'You are just an ordinary user.' >&2
    exit 1
fi

결론

UNIX/Linux 환경은 마음에 들지 않지만 매우 다양해졌습니다.즉, 휴대성(POSIX)은 생각하지도 않을 정도로 현대판 껍데기를 좋아하는 사람들이 있다는 뜻이다.그것은 오늘날 개인의 선택과 필요성의 문제이다.

가 being자의 there there there there there for for there there there for for for for라는 간단한 체크가 .root.

# Fancy red-colored `error` function with `stderr` redirection with `exit`.
error ()
{
    { printf '\E[31m'; echo "$@"; printf '\E[0m'; } >&2
    exit 1
}

# Test for root user.
if [ "$EUID" -eq 0 ]; then
    error "Do not run this as the root user"
fi

또, 실패했을 경우는, 1로 종료하는 것을 전제로 하고 있습니다.errorfunction은 출력 텍스트를 빨간색으로 설정하는 flair입니다(필요하지는 않지만 꽤 고급입니다).

@@wrikken은 @wrikken입니다.id -u을 사용법

「」를 .sudo스크립트가 루트로 동작하고 있는지 여부를 체크할 수 있습니다.않은 경우에는 을 통해 .sudo루트 권한으로 실행됩니다.

, .sudo스크립트에 필요한 모든 특수 명령어를 입력합니다.

1- GNU Linux 공식 문서를 읽어보십시오. 이를 올바르게 수행하는 방법은 여러 가지가 있습니다.

2- 해석 오류를 방지하기 위해 셸 서명을 넣어야 합니다.

#!/bin/bash

3- 이건 내 대본이야

#!/bin/bash 

if [[ $EUID > 0 ]]; then  
  echo "Please run as root/sudo"
  exit 1
else
  #do your stuff
fi

매우 간단한 방법:

if [ "$(whoami)" = "root" ]; then
    # you are root
else
    # you are not root
fi

id특정 비루트 사용자가 명령어를 실행하고 있는지 여부도 확인할 수 있습니다.

if [ "$(whoami)" = "john" ]; then
    # you are john
else
    # you are not john
fi

사용과 POSIX 비교 중 하나를 선택합니다.[... = ...] Bash 셸 의 Bash/+을 사용할 수 .[[... == ...]].

스크립트를 루트로만 실행할 수 있도록 하는 간단한 방법 중 하나는 shebang으로 스크립트를 시작하는 것입니다.

#!/bin/su root

스크립트에 루트 액세스가 실제로 필요한 경우 해당 파일 권한에 루트 액세스가 반영되어야 합니다.루트 사용자가 아닌 사용자가 루트 스크립트를 실행할 수 있도록 하는 것은 위험 플래그가 됩니다.액세스 제어는 사용하지 않는 것이 좋습니다.ifdisclossible을 클릭합니다.

chown root:root script.sh
chmod u=rwx,go=r script.sh

다음 코드를 사용해 보십시오.

#!/bin/sh

if [ "$(id -u)" -ne 0 ]; then
    echo "Sorry, you are not root." >&2
    exit 1
fi

편집에 관한 주의사항:현재 백틱은 더 이상 사용되지 않는 것으로 간주됩니다(많은 추가 노트).

의 문제:id -u,$EUID ★★★★★★★★★★★★★★★★★」whoamifalse positive는 false positive는?

$ fakeroot

id:

$ id -u
0

$EUID:

$ echo $EUID
0

whoami:

$ whoami
root

후,할 수 있는 해킹) 은, 할 수 하는 것입니다./root★★★★★★★★★★★★★★★★★★:

$ ls /root >/dev/null 2>&1 && is_root=true || is_root=false; echo "$is_root"

id -u 보다 훨씬 낫다whoamiAndroid와 같은 일부 시스템은 root이라는 단어를 제공하지 않을 수 있기 때문입니다.


명령어 예:

# whoami

출력 예:

whoami: unknown uid 0

제가 알기로는 올바른 확인 방법은 다음과 같습니다.

#!/bin/sh

if [ "$(id -u)" -eq 0 ]; then
    echo "You are root."
else
    echo "You are NOT root." >&2
fi

OP 메모: linuxcommand.org에서 "루트 테스트" 섹션을 참조할 수 있습니다.

편집자 메모:이 셸 스니펫은 POSIX에 대응하도록 약간 조정했습니다.

root인지 확인하고 그렇지 않으면 종료합니다.

if ((EUID != 0)); then
    echo "Root or Sudo  Required for script ( $(basename $0) )"
    exit
fi

또는 이 예에서는 루트 위치에 디렉토리를 만들고 권한이 상승된 후 시도합니다.

사용자가 루트인지 확인하고 가능하면 상승하지 않는지 확인합니다.

# Fails to create these dirs (needs sudo)
mkdir /test-dir-$(basename $0)
rmdir /test-dir-$(basename $0)

if ((EUID != 0)); then
    echo "Granting root privileges for script ( $(basename $0) )"
    if [[ -t 1 ]]; then
        sudo "$0" "$@"
    else
        exec 1> output_file
        gksu "$0" "$@"
    fi
    exit
fi
echo "Root privileges granted..."
# Creates Dirs as it now has rights
mkdir /test-dir-$(basename $0)
rmdir /test-dir-$(basename $0)

를 할 때는 해 주십시오.sudo' 또는 환경이 ' 컨텍스트'로 전환됩니다root.

하지만 티오는 무슨 뜻이지?

우리 젊은 파다완, 이 말은... ★★★★★★★★★★★…padawan실드)를 합니다.~를 사용하여 를 참조해 주세요.sudo가 확장될 마다 bash가 확장됩니다~가 되다/root and/home/<user>이 (이 경우)/home/padawan, 은 「」가 됩니다root padawan이치노

를 들어, 이 .install-app.sh:

#!/bin/bash
ROOT_UID=0   # Only users with $UID 0 have root privileges.
E_NOTROOT=87 # Non-root exit error.

## Prevent the execution of the script if the user has no root privileges
if [ "${UID:-$(id -u)}" -ne "$ROOT_UID" ]; then
    echo 'Error: root privileges are needed to run this script'
    exit $E_NOTROOT
fi
...
mkdir -vp ~/app/init
touch config
...
touch /home/<user>/app/init/profile
service mysql start
...

사용해서 달리면sudo:

sudo install-app.sh

및 「」가 됩니다.config을 사용하다

##
## ~ (/root)
drwxr-xr-x 17 root root    4096 Nov 23 20:45 ./
drwxr-xr-x  5 root root    4096 Nov 15 19:04 ../
...
drwxr-xr-x  3 root root    4096 Nov 25 14:30 app/
...
drwxr-xr-x  2 root root    4096 Nov 16 19:08 tmp/

## ~/app (/root/app)
drwxr-xr-x  3 root root 4096 Nov 25 14:30 ./
drwxr-xr-x 17 root root 4096 Nov 25 14:33 ../
drwxr-xr-x  2 root root 4096 Nov 25 14:33 init/

## ~/app/init (/root/app/init)
drwxr-xr-x 2 root root 4096 Nov 25 14:33 ./
drwxr-xr-x 3 root root 4096 Nov 25 14:30 ../
-rw-r--r-- 1 root root    0 Nov 25 14:33 config

## /home/<user>/app/conf
drwxr-xr-x 2 <user> <user> 4096 Nov 25 14:43 ./
drwxr-xr-x 3 <user> <user> 4096 Nov 25 14:30 ../
-rw-r--r-- 1 root   root      0 Nov 25 14:43 profile

너도 알다시피 그녀는 대본이 완전 엉망이야., 이제 ㅇㅇ, ㅇㅇ.<user> 할 수 profile할 수 .config 없이sudo처음에는 중요하지 않지만, 프로젝트가 커지면 누군가가 스크립트를 실행하고 시스템을 망가뜨릴 것입니다.

권고

권장사항은 사용자에게 sudoer인지 아닌지를 확인하는 것입니다. 다음에 ㄹ게요 하다를 더하세요.sudo이치노

이 변경을 스크립트에 적용하는 방법은 다음과 같습니다.

#!/bin/bash
E_NOTROOT=87 # Non-root exit error.

## Prevent the execution of the script if the user has no root privileges
## Check if is sudoer
if ! $(sudo -l &>/dev/null); then
    echo 'Error: root privileges are needed to run this script'
    exit $E_NOTROOT
fi
...
mkdir -vp ~/app/init
touch config
...
touch /home/<user>/app/init/profile
sudo service mysql start
...

이 변경을 통해 사용자는 다음과 같이 스크립트를 실행할 수 있습니다.

install-app.sh

사용자가 sudoer인지 확인하기 위해 비밀번호를 입력하도록 요구됩니다. 후 나,,,mkdir -vp ~/app/init사용자의 홈에 파일이 생성됩니다.

/home/<user>/app/init
/home/<user>/app/init/config
/home/<user>/app/init/profile

또, 유저용 homer 디렉토리를 취득해, 상수로 사용하는 것을 추천합니다.

## Defines user home directory
USER_HOME_DIR=$(getent passwd ${SUDO_USER:-$USER} | cut -d: -f6)
...
mkdir -vp "$USER_HOME_DIR/app/init"
...

나는 같은 문제에 부딪쳤다. " " "#!/bin/su root는 우아한 방법이지만 @basickarl에서 설명한 것처럼 특정 버전의 bash에서는 동작하지 않습니다.이 방법은, 「이러다」로 하면, 합니다./bin/bash ./some_script.(b)sh.

SO에서 환경변수를 사용하는 다른 페이지를 찾았습니다.SUDO_UID ★★★★★★★★★★★★★★★★★」SUDO_USER사용되었습니다.의 유저가, 「」로를 기동했을 .sudo스크립트에서 사용할 수 있습니다.그렇지 않으면 비어 있습니다.또한 루트로 실제로 로그온한 경우 이러한 값도 비어 있습니다(또는 완전히 확실하지 않음).

현재 사용하고 있는 솔루션은 다음과 같습니다.

isSudo()
{
  local _fn="${FUNCNAME[0]}"
  if [[ $(/usr/bin/id -u) -eq 0 ]] ; then
    if [[ ! -z "$SUDO_UID" && ! -z "$SUDO_USER" ]] ; then
      >2 echo -e "$_fn: invoked as sudo-user ($SUDO_USER)."
    else
      >2 echo -e "$_fn: invoked as root ($SUDO_USER)."
    fi
    return 0
  fi
  >2 echo "$_fn: not as root or as sudoer."
  return 1
}

그런 다음 다음과 같이 사용합니다.

if $(isSudo) ; then
  echo -e "Script started as root or as sudoer."
else
  echo -e "Script not started as root or with sudo"
fi

>2에 있는 은, 것입니다. 않으면 stderr, stderr, stderr, stderr의 리다이렉트입니다.그 이외의 경우는,if 로컬 "root " "user"를 root suer를 실행할 수 .case뭇매를 맞다

how_invoked()
{
  local _invoked_as="USER"
  if [[ $(/usr/bin/id -u) -eq 0 ]] ; then
    if [[ ! -z "$SUDO_UID" && ! -z "$SUDO_USER" ]] ; then
      _invoked_as="SUDOER"
    else
      _invoked_as="ROOT"
    fi
  fi
  echo -n "$_invoked_as" # -n prevents newline
}

그리고 이렇게 사용하세요.

INVOKED_AS=$(how_invoked)
case $INVOKED_AS in
  USER)
    echo -e "Invoked as user." ;;
  SUDOER)
    echo -e "Invoked as sudoer." ;;
  ROOT)
    echo -e "Invoked as root." ;;
  *)
    echo -e "I'm confused" ;;
esac

또는 다음 중 하나를 테스트하는 경우:

if [ "$(how_invoked)" == "SUDOER" ] ; then
  echo -e "You are a sudoer."
else
  echo -e "You are NOT a sudoer."
fi

이게 도움이 됐으면 좋겠다.

나의 원라이너:

[ "$(whoami)" != root ] && echo "Please, run as root." >&2 && exit 1

Debian, Ubuntu 및 Docker에서 테스트.

내 의견으로는, 배쉬에서 뛰고 있어.

#!/bin/bash

# Display the UID variable
echo "Your UID is $UID"

# Check for root user via UID
if [ "$UID" -eq 0 ]; then
    echo "You are root"
else
    echo "You are not root user" >&2
fi

root"Bash", "Bash" :

#!/bin/bash

if [ "$UID" -eq 0 ]; then
    echo "You are root."
else
    echo "You are just an ordinary user." >&2
fi

언급URL : https://stackoverflow.com/questions/18215973/how-to-check-if-running-as-root-in-a-bash-script

반응형