私は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
が必要なのですか?
Cronは、ユーザーまたはルートシェルとは別に、特別なシェルからコマンドを実行します。このシェルは、ユーザーと同じPATH変数にアクセスできません。したがって、スクリプトをcronジョブとして実行する場合、2つのオプションがあります。
A.スクリプト内のすべてのコマンドの完全パスを指定します(つまり、aptitude- cronへの完全パスでは、「apt-get」を探す場所がわかりません)。
B.ちょっとしたトリック-cronジョブ行を書くときは、ROOT crontabでも、スクリプトパスの前にSudoを追加します。これにより、cronがだまされて、cronシェルではなくルートシェルからスクリプトを実行し、すべてのルートのPATH変数にアクセスできるようになります。
これは、cronが非特権ユーザーとして実行されており、apt-get
コマンドを実行するには、root(別名管理)昇格特権が必要です。
別の方法は、root
ユーザーのcrontabでこのコマンドを実行することです。
Sudo -i
<type user password>
crontab -e
最初のコマンドは、シェル全体をrootに昇格し、さらに、決定的に-昇格された特権を持つユーザーとして単一のコマンドではなく、rootの環境へのアクセスを提供します。
2番目のコマンドは、自分のルートではなく、ルートのcrontabを編集します。