質問: `cron`のジョブの動作を作成するときに `bash -c` を用いて ``` 30 12 * * 1-5 bash -c 'export PATH="/usr/local/bin:/opt/rbenv/bin:$PATH"; eval "$(rbenv init -)"; cd /opt/foo; /opt/rbenv/shims/ruby foo.rb' ``` のように必要な環境変数などを設定して実行するのですが、どうしてもシェル上の環境と異なってしまいエラーになることがあります。 そのような時にはいつも1分後にタスクを設定して動作を確認しているのですが 1~59秒間待たずにcrontabのリストから即座に特定のタスクを実行する方法はないでしょうか? 環境はUbuntu14.04を使用しています。
回答: Debian / Ubuntu なら faketime というパッケージが標準で用意されており、これを用いれば `faketime` 下で動作するプロセスの日時や時間の進む速さを騙すことができます。 ``` $ sudo apt-get install faketime $ faketime -f x10 bash -c 'while :; do sleep 1; date;done' ``` これが利用できるかと手元の `cron` を `faketime` を介して起動させてみたのですが、 残念ながら騙せませんでした。 cron ジョブを即座に実行する方法ではありませんが、bash の rc によって設定される環境を利用して cron ジョブを実行したいのであれば、bash に `-l` オプションを付与してログインシェルとして起動するようにしてみてください。 ``` 30 12 * * 1-5 bash -lc 'export PATH="/usr/local/bin:/opt/rbenv/bin:$PATH"; eval "$(rbenv init -)"; cd /opt/foo; /opt/rbenv/shims/ruby foo.rb' ``` 余談ですが、シェルで複数のコマンドを実行するとき、続くコマンドが先のコマンドの実行結果に依存している場合は、コマンドを `;` で区切るのではなく `&&` で区切ったほうが安全です。これによりコマンドが失敗した時点で中断できます。 ``` 30 12 * * 1-5 bash -lc 'export PATH="/usr/local/bin:/opt/rbenv/bin:$PATH"; eval "$(rbenv init -)" && cd /opt/foo && /opt/rbenv/shims/ruby foo.rb' ``` もしくは `set -e` を先に実行したほうがいいです。 ``` 30 12 * * 1-5 bash -lc 'set -e; export PATH="/usr/local/bin:/opt/rbenv/bin:$PATH"; eval "$(rbenv init -)"; cd /opt/foo; /opt/rbenv/shims/ruby foo.rb' ```