23471


Railsで`whenever`を使い下記のように`time`で実行にかかった記録を残しながら定期処理を行っています。

[code]

    path = 'PATH="/opt/rbenv/bin:$PATH";'
    env = '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
    
[/code]

ただ、`time`コマンドの出力が標準出力ではなく標準エラーに行われるため正常終了した時は`log/foo.log`に処理時刻を残しておきたいのに常に`error_foo.log`側に保存されてしまいます。

`time`の結果を標準出力に飛ばす方法、もしくは`time`相当の処理を行い結果を標準出力に行うプログラムなどありますか？


CC BY-SA 3.0
2016-03-26T01:26:57.380
23469
2016-03-26T03:38:25.787
3271
question
ruby-on-rails linux
timeコマンドの出力を標準エラーではなく標準出力に行う方法


> `time` の結果を標準出力に飛ばす方法

`time 2>&1`  
とすると、標準エラー出力が標準出力として出力されます。  
Railsは詳しくないのですが、  
`env = 'eval "$(rbenv init -)"; cd :path && :environment_variable=:environment
nice -n 10 time 2>&1'`  
とすればできると思います。

・[cmd > /dev/null 2>&1」の話](http://qiita.com/sue71/items/cef17fabd180f4121f9e)  
・[標準エラー出力をファイルへ出力 - リダイレクトとパイプ -
コマンドプロンプトの使い方](http://www.adminweb.jp/command/redirect/index3.html)  
・[[Bash]標準出力・標準エラー出力の全て（1>&2とか）まとめ | Coffee Breakにプログラミング備忘録](http://to-
developer.com/blog/?p=1001)


CC BY-SA 3.0
2016-03-26T03:03:17.703
23470
2016-03-26T03:03:17.703
8621
23469
answer


Rubyからどういったシェルが起動されるか知りませんが、`sh`や`bash`の話として書きます。

### 一般の話

標準エラー出力（FD: 2）を標準出力（FD: 1）に接続するにはリダイレクトで`2>&1`とします。  
パイプで繋げるのが目的ならば短縮記法の`|&`も使えます。

[code]

    # timeの（標準エラー）出力もnlに渡り行番号が付く
    nice -n 10 time ls 2>&1 |nl
    # パイプに繋げるなら短縮記法もある
    nice -n 10 time ls |& nl
    
[/code]

### （Bash内部コマンドでない）timeの機能

質問者さんが使っている`time`は`nice`から起動される物なので、外部コマンドの`time`です。  
argusさんのコメントのように多分`-o`オプションがあります。

[code]

    # 出力先に/dev/stdoutを指定
    nice -n 10 time -o /dev/stdout ls |nl
    
[/code]

### Bash内部コマンドのtimeの場合

`Bash`を使っている場合、niceに起動させずに普通に`time`を実行すると`bash`の内部コマンドの`time`が実行されます。  
しかし、上記の方法は内部コマンドの`time`には使えません。

[code]

    # timeの出力には行番号が付かない
    time ls 2>&1 |nl
    
[/code]

とした場合、標準出力に接続されるのは`ls`のエラーだけです。  
通常はこの方が便利だからです。  
これは`time`が`bash`の組込みコマンドであるからこそ実現できる機能です。

`time`を含んだ全体のリダイレクトを指定する場合は、コマンド列をサブシェルで起動するよう明示する必要があります。  
それら全体にリダイレクトを指定します。

[code]

    # 全てに行番号が付く
    (time ls) 2>&1 |nl
    
[/code]

サブシェルでなく普通にシェルのプロセスを起動してもよいです。

[code]

    bash -c 'time ls' 2>&1 |nl
    
[/code]


CC BY-SA 3.0
2016-03-26T03:38:25.787
23471
2016-03-26T03:38:25.787
3054
23469
answer