我正在编写一个需要根级权限的脚本,我想让它这样做,如果脚本不是以根身份运行,它只是回显“请以根身份运行”并退出。

下面是我正在寻找的一些伪代码:

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

  else (do stuff)
fi

exit

我怎样才能最好地(干净和安全地)完成这个任务呢?谢谢!

啊,只是澄清一下:(做东西)部分将涉及运行本身需要root的命令。因此,作为一个普通用户运行它只会出现一个错误。这只是为了干净地运行一个需要根命令的脚本,而不需要在脚本中使用sudo,我只是在寻找一些语法糖。


当前回答

我无意中发现了同样的问题。行#!/bin/su root将是一个优雅的方法,但在某些(高级)bash版本上不起作用,就像@basickarl提到的那样。此外,当您使用/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

在echo前面的>2是为了将echo重定向到stderr,否则if语句就会失控,这只是为了进行一点调试。你可以在局部变量中保存“root”、“sudoer”或“user”,然后让函数将其回显,然后执行一个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

希望这能有所帮助。

其他回答

已经给出了一些答案,但似乎最好的方法是使用:

id - u 如果以root身份运行,将返回id为0。

这似乎比其他方法更可靠,即使通过sudo运行脚本,它似乎也会返回一个id为0。

我无意中发现了同样的问题。行#!/bin/su root将是一个优雅的方法,但在某些(高级)bash版本上不起作用,就像@basickarl提到的那样。此外,当您使用/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

在echo前面的>2是为了将echo重定向到stderr,否则if语句就会失控,这只是为了进行一点调试。你可以在局部变量中保存“root”、“sudoer”或“user”,然后让函数将其回显,然后执行一个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

希望这能有所帮助。

我检查的根用户,运行在Bash:

#!/bin/bash

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

在bash脚本中,有几种方法可以检查正在运行的用户是否是root用户。

作为警告,不要使用root用户名检查用户是否为root。没有什么能保证ID为0的用户被称为root。这是一个被广泛遵循的强大约定,但任何人都可以为超级用户重命名其他名称。

我认为使用bash时最好的方法是使用$EUID,从手册页:

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

这是一种比$UID更好的方法,因为$UID可以更改,并且不能反映运行脚本的真实用户。

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

我解决这类问题的一种方法是,当我的命令不是以root身份运行时,在命令中注入sudo。这里有一个例子:

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

这样,当使用超级用户时,我的命令由root运行,当由普通用户运行时,由sudo运行。

如果您的脚本总是由根用户运行,只需相应地设置权限(0500)。

我的小笑话:

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