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


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

キャッシュなどをクリアし、ターミナルで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..."

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



2
@muru。ただし、他の質問は反対です。rootとして実行している場合はスクリプトを失敗させます。
ステファンシャゼラス

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

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

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

$ bash -c 'echo $EUID'
1000

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

ユーザーがこれを行った場合、明らかに特権のエスカレーションにつながることはありませんが、スクリプト内のコマンドが実行すべきことを実行できず、間違った所有者などでファイルが作成される可能性があります。


1
注:Solarisの5.10に、/bin/id -u与え/bin/id: illegal option -- u Usage: id [-ap] [user]
モニカjrw32982サポート

1
@ jrw32982 SolarisのPOSIXユーティリティにアクセスするに/usr/xpg4/binは、早い段階で必要$PATHです。
クサラナナンダ

1
ポイントは、の-uオプションidは普遍的ではないため、この解決策は普遍的でidあり、POSIXバージョンのPATHで最初に発生しなければならないという警告のみです。
jrw32982は

1
@ jrw32982 Solarisでスクリプトが正しいPOSIXユーティリティを取得するために、スクリプト$PATHの先頭をの/usr/xpg4/bin前になるように変更し/binます。非POSIXの使用を主張する場合idは、明らかに、よりポータブルなソリューションを考え出す必要があります。
クサラナナンダ

1
@Harryはい、スクリプトはPATH=$( getconf PATH )他の明示的なデフォルトパスを使用または設定するか、を呼び出すために明示的なパスを使用できますid
クサラナナンダ

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通常あなたに認証されたユーザーを与えるが、それに頼ることは、非常に脆いです。これは、シェルによって設定されていないが、通常(のような認証コマンドで設定されているloginsuGNU / Linuxシステムで、必ずしも他)、上(sudosshd少なくともopensshのから(1)...)。ただし、常にそうとは限りません(uidを変更しても自動的にその変数が設定されるわけではなく、uidを変更するアプリケーションによって明示的に行う必要があります)。また、シェルの先祖の他のプロセスによって変更されることもあります。$LOGNAME、POSIXで指定されている(同じ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を使用せず、ゼロと比較することは、カーネルが実際に実行しているテストによりよく一致します。カーネルが気にするのは、パスワードファイルの名前ではなく、IDだけです。
イカ

6
使用する$(id -u)方が良いと思います。いくつかの(悪意のある)ケースで$USERは、間違っている可能性があります。
バジルスタリンケビッチ

1
@Jesse_bが提供するリンクに興味がある人のために:タイプミスがあります。それはする必要がありますgnu.org/software/bash/manual/bashref.html
krytenを

1
一部のシステムは、uid 0を持つ特権アカウントの名前として「ルート」を使用しません。QNAPは1つとして思い浮かびます。そのため、rootアカウント名ではなく、uid 0のみをチェックする必要があります。
ロアイマ

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

非rootユーザーがスワップをオフにしますか?
クサラナナンダ

2
はい。SELinuxでこれを設定できます。同様に、ルートプロセスの実行を無効にすることができます。
その他の男

1
exitユーザーが現在の特権でできる限りのことをしたい場合に、何かが失敗した後はしたくないかもしれません。(しかし、これがすべてrootを必要とする典型的なシステムでは、終了するほうがより便利で、ノイズが少なくなります。)
Peter Cordes

2
あなたがrootであるかどうかを確認することは「悪い習慣」だとは言いません。特に、それがまさにあなたが知りたいことなら。あなたがやりたいことをするのに十分な権限を持っているかどうかをチェックするのが最善であるとあなたの主張をします。
エリックベネット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.