1. ホーム
  2. bash

[解決済み] STDOUTとSTDERRの両方をターミナルとログファイルに出力するにはどうすればよいですか?

2022-05-27 19:16:46

質問

技術者でないユーザーが対話的に実行するスクリプトがあります。このスクリプトは、ユーザーがスクリプトが問題なく実行されていることを確認できるように、STDOUT にステータスの更新を書き込みます。

私は、STDOUT と STDERR の両方をターミナルにリダイレクトさせたいと思います (ユーザーがスクリプトが動作していることを確認し、また問題があったことを確認できるようにするため)。また、両方のストリームをログ ファイルにリダイレクトさせたいと思います。

ネット上でたくさんの解決策を見ました。うまくいかないものもあれば、恐ろしく複雑なものもあります。私は実行可能なソリューションを開発しましたが (これは回答として入力されます)、それは不器用です。

完璧なソリューションは、ターミナルとログ ファイルの両方に両方のストリームを送信する任意のスクリプトの先頭に組み込むことができる 1 行のコードでしょう。

EDIT。 STDERRをSTDOUTにリダイレクトし、結果をteeにパイプすることは機能しますが、それはユーザーがリダイレクトとパイプ出力を覚えていることに依存します。私は、ロギングが確実で自動的であることを望みます (これが、スクリプト自体にソリューションを埋め込むことができるようにしたい理由です)。

どのように解決するのですか?

ファイルや画面へのリダイレクトには "tee" を使用します。 使用するシェルによっては、標準エラー出力を標準エラー出力にリダイレクトする必要があります。

./a.out 2>&1 | tee output

または

./a.out |& tee output

csh には "script" という組み込みコマンドがあり、画面に表示されるすべてのものをファイルに取り込むことができます。 script" とタイプして起動し、キャプチャしたいことを何でもやってから、control-D を押してスクリプトファイルを閉じます。 sh/bash/kshに相当するものは知りません。

また、これらはあなた自身の sh スクリプトであり、あなたが修正できることを示したので、次のようにスクリプト全体を中括弧またはブラケットで囲むことによって、内部でリダイレクトを行うことができます。

  #!/bin/sh
  {
    ... whatever you had in your script before
  } 2>&1 | tee output.file