質問: 'eval "$(rbenv init -)"; cd :path && :environment_variable=:environment nice -n 10 time' job_type :rbenv_rake, %Q{#{path} #{env} :bundle_command rake :task --silent :output} set :output, {error: 'log/error_foo.log', standard: 'log/foo.log'} every '0 8 * * *' do rbenv_rake 'foo:update' end ``` ただ、`time`コマンドの出力が標準出力ではなく標準エラーに行われるため正常終了した時は`log/foo.log`に処理時刻を残しておきたいのに常に`error_foo.log`側に保存されてしまいます。 `time`の結果を標準出力に飛ばす方法、もしくは`time`相当の処理を行い結果を標準出力に行うプログラムなどありますか?
回答: Rubyからどういったシェルが起動されるか知りませんが、`sh`や`bash`の話として書きます。 ### 一般の話 標準エラー出力(FD: 2)を標準出力(FD: 1)に接続するにはリダイレクトで`2>&1`とします。 パイプで繋げるのが目的ならば短縮記法の`|&`も使えます。 ``` # timeの(標準エラー)出力もnlに渡り行番号が付く nice -n 10 time ls 2>&1 |nl # パイプに繋げるなら短縮記法もある nice -n 10 time ls |& nl ``` ### (Bash内部コマンドでない)timeの機能 質問者さんが使っている`time`は`nice`から起動される物なので、外部コマンドの`time`です。 argusさんのコメントのように多分`-o`オプションがあります。 ``` # 出力先に/dev/stdoutを指定 nice -n 10 time -o /dev/stdout ls |nl ``` ### Bash内部コマンドのtimeの場合 `Bash`を使っている場合、niceに起動させずに普通に`time`を実行すると`bash`の内部コマンドの`time`が実行されます。 しかし、上記の方法は内部コマンドの`time`には使えません。 ``` # timeの出力には行番号が付かない time ls 2>&1 |nl ``` とした場合、標準出力に接続されるのは`ls`のエラーだけです。 通常はこの方が便利だからです。 これは`time`が`bash`の組込みコマンドであるからこそ実現できる機能です。 `time`を含んだ全体のリダイレクトを指定する場合は、コマンド列をサブシェルで起動するよう明示する必要があります。 それら全体にリダイレクトを指定します。 ``` # 全てに行番号が付く (time ls) 2>&1 |nl ``` サブシェルでなく普通にシェルのプロセスを起動してもよいです。 ``` bash -c 'time ls' 2>&1 |nl ```