web-dev-qa-db-ja.com

ルートでない場合にスクリプトの実行を停止する方法(そして「ルートとして実行されていません!終了しています...」とエコーします)

これが私のソースです:

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

キャッシュなどをクリアし、ターミナルでrootとして実行する必要があることをエコーし​​ます。基本的に、スクリプトがrootとして実行されていないことが検出された場合は、スクリプトの実行を停止したいだけです。

例:

"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..."

管理者特権で実行する場合は、通常どおり実行されます。何か案は?ありがとう!

17
M. Knepper
#!/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

RootユーザーのUIDは0です(「root」アカウントの名前に関係なく)。 id -uによって返される有効なUIDがゼロでない場合、ユーザーはroot権限でスクリプトを実行していません。 id -ruを使用して、実際のID(ユーザーのUID invokingスクリプト)に対してテストします。

権限のないユーザーによって変更される可能性があるため、スクリプトでは$EUIDを使用しないでください。

$ bash -c 'echo $EUID'
1000

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

ユーザーがこれを行った場合、明らかに特権の昇格は行われませんが、スクリプトのコマンドが本来の目的を実行できなくなり、ファイルが間違った所有者で作成されるなどの可能性があります。

47
Kusalananda

私が望むのは、スーパーユーザー権限があること、つまり、実効ユーザーIDが0であることを確認することです。

zshbash$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またはzsh$USERNAME変数は、uidのfirstユーザー名を取得することに注意してください。 IDが0である他のユーザーがいるシステムでは、プロセスがrootとして認証されている子孫であっても、rootにならない場合があります。

$USER通常認証されたユーザーを提供しますが、それに依存することは非常に脆弱です。シェルでは設定されませんが、通常は認証コマンド(loginsu(GNU/Linuxシステムでは必ずしも他のシステムではない)など)、Sudosshd(少なくともopensshからのもの)...)。ただし、常にそうであるとは限りません(uidを変更しても、自動的にその変数が設定されるわけではありません。uidを変更するアプリケーションで明示的に行う必要があります)。また、シェルの祖先の他のプロセスによって変更されている可能性もあります。 $LOGNAME、POSIXで指定されているため、同じ警告がより信頼性が高い(元はFIPS 151-2)から)

19

$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
12
jesse_b

実際に必要なのは、これらの操作を実行するアクセス権があるかどうかを判断することです。それの代わりに自分がrootであるかどうかを確認することは悪い習慣だと考えられています。

Root以外のユーザーがスワップおよびドロップページキャッシュを変更できるようにシステムが構成されている場合、そのユーザーはスクリプトを実行できないのはなぜですか?

代わりに、操作を試して、失敗した場合に役立つメッセージを表示して終了することができます。

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
10
that other guy