web-dev-qa-db-ja.com

成功時にのみシェルコマンドの出力を非表示にしますか?

シェルコマンドの出力を非表示にする 通常、stderrおよびstdoutをリダイレクトする必要があります。デフォルトで出力を非表示にする組み込みの機能またはコマンドはありますか?ただし、エラー時には、累積されたすべての出力をダンプしますか?これをリモートsshコマンドのラッパーとして実行したいと思います。現在、リダイレクトを使用していますが、失敗の原因についての手がかりはなく、冗長すぎます。

EDIT:最後に、@ Belminの回答に基づいて次のテンプレートを作成しました。これを少し調整して、スクリプトからの以前のすべてのコマンドを蓄積しました、現在のプロセスIDを使用し、ログを自動的に削除し、問題が発生したときに赤のエラーメッセージを追加します。このテンプレートでは、ディレクトリが既に存在するため、最初のsilentラッパーは成功し、3番目のコマンドは失敗します。

#!/bin/sh

set -e

SILENT_LOG=/tmp/silent_log_$$.txt
trap "/bin/rm -f $SILENT_LOG" EXIT

function report_and_exit {
    cat "${SILENT_LOG}";
    echo "\033[91mError running command.\033[39m"
    exit 1;
}

function silent {
    $* 2>>"${SILENT_LOG}" >> "${SILENT_LOG}" || report_and_exit;
}

silent mkdir -v pepe
silent mkdir -v pepe2
silent mkdir -v pepe
silent mkdir -v pepe2

私は bash function を次のように設定します:

function suppress { /bin/rm --force /tmp/suppress.out 2> /dev/null; ${1+"$@"} > /tmp/suppress.out 2>&1 || cat /tmp/suppress.out; /bin/rm /tmp/suppress.out; }

次に、次のコマンドを実行します。

suppress foo -a bar
3

このためのスクリプトを作成するのは簡単です。

この完全にテストされていないスクリプトのようなもの。

OUTPUT=`tempfile`
program_we_want_to_capture &2>1 > $OUTPUT
[ $? -ne 0 ]; then
    cat $OUTPUT
    exit 1
fi
rm $OUTPUT

一方、スクリプトの一部として実行するコマンドについては、通常、すべての出力を出力するだけではなく、もっと良いものを望んでいます。私はよく目にするものを未知のものに制限します。これは、10年以上前に読んだものを元にしたスクリプトです。

#!/bin/bash

the_command 2>&1 | awk '
BEGIN \
{
  # Initialize our error-detection flag.
  ErrorDetected = 0
}
# Following are regex that will simply skip all lines
# which are good and we never want to see
/ Added UserList source/ || \
/ Added User/ || \
/ init domainlist / || \
/ init iplist / || \
/ init urllist / || \
/ loading dbfile / || \
/^$/ {next} # Uninteresting message.  Skip it.

# Following are lines that we good and we always want to see
/ INFO: ready for requests / \
{
  print "  " $0 # Expected message we want to see.
  next
}

# any remaining lines are unexpected, and probably error messages.  These will be printed out and highlighted.
{
  print "->" $0 # Unexpected message.  Print it
  ErrorDetected=1
}

END \
{
  if (ErrorDetected == 1) {
    print "Unexpected messages (\"->\") detected in execution."
    exit 2
  }
}
'
exit $?
7
Zoredache

これを行うための明確な方法はないと思います、私が考えることができる唯一のことは

  • コマンドの出力をキャプチャします。
  • コマンドの戻り値と、失敗したかどうかを確認します
    • キャプチャした出力を表示します。

これを実装することは興味深いプロジェクトかもしれませんが、おそらくQ&Aを超えています。

5
user9517

そうしよう:

out=`command args...` || echo $out
1
user2743554

tehcommand &>/tmp/$$ || cat /tmp/$$のようなもので不足する

どれだけのユーザビリティ/タイピングが必要/必要かによって異なります。 (例:パイプとして使用するか、引数でコマンドを渡す)

@zoredacheの短いスクリプトは、基本的にはこれのプロトラッパーであり、これにより堅牢性が向上し、同時実行性が処理されます。

1
rogerovo