あるプロセスから別のプロセスに出力をパイプするにはどうすればよいですか?ただし、最初のプロセスに出力がある場合にのみ実行しますか?

あるプロセスから別のプロセスに出力をパイプするにはどうすればよいですか?ただし、最初のプロセスに出力がある場合にのみ実行しますか?

出力がある場合は、電子メールを送信するようにこのコマンドをどのように書き換えることができますかmailq | grep

mailq | egrep 'rejected|refused' -A 5 -B 5 | mail -s 'dd' email@email

一行で可能でしょうか?

バラよりパイプが空であることを確認し、空の場合は、データに対してコマンドを実行します。メールを送信するよりも一般的なケースです。

答え1

&&grepが次の一致があることを示す終了ステータスを返す場合にのみ、演算子を使用してメールコマンドを実行できるようにするには、一時ファイルを使用する必要があると思います。

TMPFILE=`mktemp /tmp/mailqgrep.XXXXXX`; mailq | egrep 'rejected|refused' -A5 -B5 > "$TMPFILE" && mail -s 'dd' email@email < "$TMPFILE"; rm "$TMPFILE"

一時ファイルがどこかに残っていても大丈夫で静的名を使用できる場合は、特別な命名と削除操作をスキップできます。

 mailq | egrep 'rejected|refused' -A5 -B5 > /tmp/mailqgrep && mail -s 'dd' email@email < /tmp/mailqgrep

編集する:見た後グレンの答え私はもう少し遊ん$()で構文を使用して変数を割り当てると、コマンドの終了コードが返されるので、文字列の長さのテストをスキップして使用できます。これはすべて1つのコマンドで行われます。

data=$(mailq | egrep 'rejected|refused' -A 5 -B 5) && mail -s 'dd' email@email <<< "$data"

編集2:見た後サイモンの答え私は私のmailプログラムを確認しました。彼が説明したデフォルト値と同じようには機能しませんが、オプションがあります。マニュアルページから:

-E送信メッセージの最初または唯一のメッセージ部分にテキストが含まれていない場合は、送信されずに自動的に削除され、プログラムの起動時に Skipemptybody 変数が効果的に設定されます。これは、cron(8)によって開始されたスクリプトからメッセージを送信するのに役立ちます。

これを可能にしなさい:

mailq | egrep 'rejected|refused' -A 5 -B 5 | mail -E -s 'dd' email@email

答え2

公益事業もし標準入力が空でない場合は、コマンドを実行するために明示的に存在します。

mailq | egrep 'rejected|refused' -A 5 -B 5 | ifne mail -s 'dd' email@email

ifne コマンドはその他のユーティリティパッケージは、「Unixがまだ幼い頃、ずっと前には誰も作成するつもりがなかった、ますます増えるUnixツールバー」と評価されます。

答え3

出力を変数に保存し、文字列の長さがゼロ以外の場合はmailコマンドを呼び出すことができます。

data=$(mailq | egrep 'rejected|refused' -A 5 -B 5)
[[ -n "$data" ]] && mail -s 'dd' email@email <<< "$data"

1行に2つのコマンドをセミコロンで連結します。

答え4

この特別なケースではmailこの-Eオプションをサポートする場合、ちょうど使用してください。通常、単語を読み取ろうとします。単語がある場合は、後処理コマンドを開始し、ファイルの残りの部分にその文字を入力します。

pipe_if_not_empty () {
  a=$(dd bs=1 count=1 2>/dev/null; echo .)  # read at most one character
  if [ "$a" != "." ]; then                  # if there were two characters,
    { printf %s "${a%.}";                   # then output the first character
      cat; } |                              # and the rest of the input   
    "$@"                                    # into the specified program
  fi
}

mailq | egrep 'rejected|refused' -A 5 -B 5 |
pipe_if_not_empty mail -s 'dd' email@email

noteの有用な用途cat。追加すると、echo .入力の最初の文字が改行であっても機能は機能します(この$(…)設定は端末の改行を削除することに注意してください)。

ほとんどのシェル(私が知っている限りzshを除くすべてのシェル)では、ファイルがヌル文字で始まる場合、このコードはそのファイルが空であると見なします。この問題を解決することは、読者の練習課題として残されます。 (ヒント:od最初のサブシェルで使用してprintf最初のバイトを印刷します。)(解決策:パイプが空であることを確認する方法)ファイルが現在のロケールで有効な文字ではなくバイトで始まる場合、同じ問題が発生する可能性があります。を使用してこのコードを実行すると、この問題を解決する方が簡単ですLC_ALL=C

関連情報