web-dev-qa-db-ja.com

ルートcronジョブスクリプトが正しく実行されるために「Sudo」が必要なのはなぜですか?

私はRaspberry Piでこの簡単なスクリプトを実行して自動更新しているので、忘れてしまいます。また、更新が成功したかどうかを示すログも保持します。スクリプトはupdate.shです。

#!/bin/bash
echo "Update starts on: $(date)" >> /home/pi/update.log
 if apt-get update && apt-get upgrade -y; then
    echo "update successful $(date)"  >> /home/pi/update.log
 else
    echo "Couldn't update $(date)" >> /home/pi/update.log
 fi

このスクリプトをSudo crontab -eを使用してルートcrontabに追加しました。cronjobは毎日午前6時に実行するように設定されています

0 6 * * * /home/pi/update.sh

シェルでSudo ./update.shを実行すると手動でコマンドが実行され、ログに「成功した」エントリが残るため、ある程度は機能することはわかっています。一方、crontabから実行すると、常に「更新できませんでした」というエントリが表示されます。重要な場合は、「update.sh」スクリプトは「pi」ユーザーによって作成されたものであり、実行権限を与えることを除いて、権限を変更したことはありません。

同じ問題に関する別の質問を読んだところ、男はコマンドの前にSudoを付けることで解決しました。彼はすでにrootによって実行されているので奇妙だと認めますが、うまくいくと言います。 Sudoを追加してみて、実際に機能することを確認しました。

なぜこれが起こるのか誰か知っていますか?すでにrootであるのに、なぜSudoが必要なのですか?

6
freejuices

Cronは、ユーザーまたはルートシェルとは別に、特別なシェルからコマンドを実行します。このシェルは、ユーザーと同じPATH変数にアクセスできません。したがって、スクリプトをcronジョブとして実行する場合、2つのオプションがあります。

A.スクリプト内のすべてのコマンドの完全パスを指定します(つまり、aptitude- cronへの完全パスでは、「apt-get」を探す場所がわかりません)。

B.ちょっとしたトリック-cronジョブ行を書くときは、ROOT crontabでも、スクリプトパスの前にSudoを追加します。これにより、cronがだまされて、cronシェルではなくルートシェルからスクリプトを実行し、すべてのルートのPATH変数にアクセスできるようになります。

8
Nick

これは、cronが非特権ユーザーとして実行されており、apt-getコマンドを実行するには、root(別名管理)昇格特権が必要です。

別の方法は、rootユーザーのcrontabでこのコマンドを実行することです。

Sudo -i
<type user password>
crontab -e

最初のコマンドは、シェル全体をrootに昇格し、さらに、決定的に-昇格された特権を持つユーザーとして単一のコマンドではなく、rootの環境へのアクセスを提供します。

2番目のコマンドは、自分のルートではなく、ルートのcrontabを編集します。

1
Craig Watson