このスクリプトがcronから実行されると失敗しますが、手動で実行されると機能するのはなぜですか?


3

私は比較的単純なbashスクリプトを持っていますが、直接起動した場合はうまくいきますが、cronで実行した場合は失敗します。これが失敗するのはなぜですか?また、どうすればそれをcron経由で機能させることができますか?

#!/bin/bash
apt-get update -y
apt-get upgrade -y
apt-get install boinc-client -y

cronが実行しようとすると、手動で呼び出すとこのエラーが発生します。

dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.

しかし、それが最初に手動で実行される限り、それはちょうどうまくいきます。

回答:


5

この種の質問に対する通常の答えは、cronジョブは非対話型の非ログインシェルで実行されるため、ほとんどのシェル起動ファイル(両方ともシステム全体の /etc ほとんどのシェル起動ファイルはログインシェル(コンピュータにログインしたときに最初に表示されるシェル)または対話型シェル(接続されているシェル)に適用されるためです。ユーザーが端末を介してそれらと対話しているためです。

そのため、実際に環境設定に依存するcronジョブにコマンドを入力した場合(以下を含む) PATH 変化)は、通常、次のような場所で発生します。 /etc/profile/etc/bashrc~/.profileまたは ~/.bashrcその設定はcronジョブでは起こりません。 cronファイル形式では、ジョブの環境変数を指定できます。そのため、指定することをお勧めします。 BASH_ENV または ENV シェル起動スクリプトでsourceを指すようにします。の「呼び出し」セクションを参照してください。 bash(1) manページ


この環境関連の提案はまさに私の問題でした。走ったとき logrotate コマンドラインから、それはうまくいったが、私が走ったとき logrotate crontabから、そうではありませんでした。私は実行可能ファイルへのフルパスを指定する必要がありました。 /usr/sbin/logrotate がなかったので) PATH 定義済み。
Mike

1

これは答えにはなりませんが、私はコメントできません。提案:

  1. bashスクリプトの前に以下を追加してください。メール出力に記録された最後の行は、失敗したコマンドになります。

    set -x
    set -e
    
    • sendmailがあることを確認します(以下のような提供パッケージをインストールします。 postfix または esmtp
    • メールリーダーをインストールする(推奨) mutt
    • メールがあなたに届くようにする
      • postfix経由(インストーラによって自動的に行われるかもしれません):追加 root: my-user-name/etc/aliases または /etc/postfix/aliases
      • cron経由:追加 MAILTO="my-user-name" 適切に crontab ファイル
  2. スクリプトが別の環境で実行されることを確認してください。 apt-getへのフルパスを指定し(apt-getが見つかったことがわかっているのでおそらく原因ではありません)、それをXの外のコンソール(端末ではない)で実行します(dpkg configureスクリプトによってはXセッションが必要です)。

    • 絶対パスを使うようにスクリプトを修正してください。 /usr/bin/apt-get update -y (正しいパスに置き換えてください)
    • を押してコンソールに切り替えます ctrl-alt-f1
    • rootユーザーに切り替えます。 sudo -i
    • 環境なしで非ログインシェルを起動します。 env -i /bin/bash --noprofile --norc (正しいパスに置き換えてください)
    • スクリプトを実行します。 /my/full/path/to/cronscript。動作しますか?
  3. スクリプトに権限がありますか?あなたはシステムcrontabを使っていますか? (もう一度、おそらく犯人ではない)

    • システムcrontabを使用していると述べたので、これはスキップします
  4. apt-getはセッションサポート(consolekitまたはsystemd)を必要としますか。しかしこれは暗闇の中での一撃です。

    • 助けになるほど十分にはわからない。

残念なことに、これらの答えは私の頭の上にあります。私は通常Linuxで作業をしていないので、これは私が扱うことはめったにありません。私はrootとしてcrontabを使っていると言えるでしょう。どこにでもログを記録する方法がわかりませんが、トラブルシューティングに役立つと思われるので、実行したことを願います。自分で狩りに行くために何を探しているのかさえわからない。
Jonathan van Clute

1

何が起こっているのかほとんど理解せずにそれを解決することができた。 root crontabから実行していたとしても、apt-getコマンドはまだそれらの前にsudoを必要としていました。論理的には、スクリプトが既に「rootとして」実行されていたので必要ではないと予想していましたが、一度sudoを追加したら...すべてが予想通りに機能しました。


それは全く予想外のことで、何にも影響を与えるべきではありませんが、うまくいったことをうれしく思います。何度もせずに試してみました sudo あなたはこれを考え出す前に?
Daniel H

私は今日のほとんどをこれに逆らって頭を叩いて過ごした。このスクリプトは、コマンドラインから手動でインスタンス化した場合は完全に実行されますが、cronから実行すると失敗します。すでにrootのcrontabから実行していたので非常に奇妙なので、sudoを追加するのに長い時間がかかったのです。最後に、他のアイデアから、私は一体何だと思った…そしてその前に、それはうまくいった。図に行きます!
Jonathan van Clute

これは環境と関係があると思います sudo セットと環境 cron セット。いずれにせよ、これがうまくいったので、あなたがあなた自身の答えを受け入れるならば、それはこのページに出くわす他の人を助けるかもしれません。そうすれば、彼らはそれを試してもうまくいくでしょうし、あるいは実際に同じ問題ではないのであれば彼らはより早く進むでしょう。
Daniel H
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.