スクリプトは、rootとして実行されているかどうかをどのように確認できますか?


104

単純なbashスクリプトを書いていますが、rootとして実行されているかどうかを確認するために必要です。おそらくそれを行うための非常に簡単な方法があることは知っていますが、その方法はわかりません。

ただ、明確にする:
スクリプト記述するための簡単な方法何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倍)高速であることが判明しました(テスト後)が、この1つの原因を受け入れていますが、すべての答えはうまくいきました。
マラバルバ

18
また、$UIDそして$EUIDbashismsです。単なるPOSIX準拠のシェルにはこれらの変数がid(1)なく、代わりに使用する必要があります。
デビッドフォースター14年

3
bashスクリプトでは、を使用できますif ((EUID)); then@ geirhaのコメントを
jfs 14年

7
@Andrew:変数はに渡される前に置換されsudoます。実行sudo sh -c 'echo $EUID'すると、期待どおりの結果が表示されます。
M.ダドリー

6
: - @Andrew私は遅く、ここで道だけど、後世のために知っている$EUID(@DavidFoersterによって前述したように)Bashismあり、そして、あなたが/bin/sh最も可能性へのリンクである/bin/dash、ではありません/bin/bashsudo bash -c 'echo $EUID'期待される結果が得られます。
エイドリアンギュンター

118

rootユーザーの名前は「root」である必要はありません。whoamiユーザーIDを持つ最初のユーザー名を返します0$USERログインしているユーザーの名前が含まれます。ユーザーIDを持つことはできますが0、名前は異なります。

アカウントがルートとしてログインしているかどうかを確認する唯一の信頼できるプログラム:

id -u

私は使用-uのための実効ユーザーID、いない-rため、実際のユーザーID。許可は、実際のユーザーIDではなく、有効なユーザーID によって決定されます。

テスト

/etc/passwd次のユーザー名とユーザーID 0が所定の順序で含まれています。

rootx
root2

としてログインするとroot2、次の結果が得られます。

  • whoamirootx
  • echo $USERroot2(プログラムは空の環境で起動した場合、これは、例えば、空の文字列を返しますenv -i sh -c 'echo $USER'
  • id -u0 ご覧のとおり、他のプログラムはこのチェックに失敗し、id -u合格しただけです。

更新されたスクリプトは次のようになります。

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

5
あなたは必要ありませんid -ubashでaskubuntu.com/questions/30148/...
JFS

5
私は常にの代わりにshdash)をインタープリターとして使用して、可能な限りPOSIXに準拠するようにしbashます。しかし、良いショットは、別のフォークを保存します:)
Lekensteyn

しばらく寒いうちに戻ってきて、見てみました。Lekensteynの方法は確かに優れているようです。彼の答えは現在、新しく受け入れられた答えです。+1、あなた、Lekensteyn、esp。この質問からバッジを取得するのは難しい;)
トーマスウォード

私の質問を受け入れてくれて長い間待ってくれてありがとう:DIはゴールドポピュリストバッジとブロンズを手に入れました。
-Lekensteyn

3
短いバージョンを見ました[ -w / ]。考え方は変わりません。注:特定のchrootsでは、存在し[ -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 ))'機能します。ところで、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' ]

コードを見て、スクリプトが失敗しないかどうかを確認します。うまくいけば、あなたの答えを受け入れます:)
トーマスウォード

4
@George Edison:、$USER特にこの方法での使用はお勧めしません。$USERログインシェルによって設定される場合、プログラムに伝播する必要はありません(env -i sh -c 'echo $USER')。そのように、$USERは空であり、構文エラーが発生します。
レーケンシュタイン

1
@Lekensteyn $USERはシェルによって設定されるだけでなく、なりすましやすいものでもあります。Whoamiは実際のユーザーを返します。
ポール・ド・フリーズ

2
@PauldeVriezeそのチェックをだますことのポイントは何ですか?
-htorque

1
@andrewsomething:$USERはシェルによって解釈されますsudo sh -c 'echo $USER'。意味を持たせるためには、例が必要です。@George:UID 0に対してwhoami常に返さrootれるという誤った仮定を行います。
samhocevar

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

スクリプトをrootでのみ実行可能にする簡単な方法の1つは、次の行でスクリプトを開始することです。
#!/bin/su root


1
これをしないでください。rootとして直接ログインしようとしますが、前者は禁止されているため、多くのシステムではsudoが必要になる場合があります。さらに、シバンは、スクリプトが設計されたもので実行されるようにすることを目的としていますが、メソッドはスクリプトをルートのデフォルトシェルで実行しますが、スクリプトが作成者以外によって実行された場合は予測できません したがって、シバンを使用してスクリプトの権限を昇格すると、移植性が著しく損なわれ、多くのシステムでエラーが発生します。(su:認証の失敗)
StarCrashr


1

このスニペットは:

  • さまざまなセッションで確認する
  • 使用することを提案する sudo !!
  • エラーを返します
if ["$(whoami&2> / dev / null)"!= "root"] && ["$(id -un&2> / dev / null)"!= "root"]
      それから
      echo "このスクリプトを実行するにはrootでなければなりません!"
      echo "use 'sudo !!'"
      1番出口
fi

1

この答えはアイデアを保存するためのものであり、あなたの一部にとって役立つかもしれません。デスクトップGUIから実行され、root権限が必要なスクリプトが必要な場合は、次の方法を試してください。

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

これにより、rootユーザーのパスワードを求めるダイアログボックスが表示されます。コマンドラインのsudoと同じです。

gksudoその後、お使いのシステムで利用できるようにして、それをインストールすることはできませんsudo apt-get install gksu


0

このコードは、EUIDを定義しないBashと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.