0

タイトルはあいまいかもしれませんが、良い例があります。

echo "Test message:\nThis is a line.\nAnd this is another." | nail -s "`tail -1`" joe@localhost

ここでの目的は、エコーの内容をメッセージ本文として送信し、最後の行を件名として使用することです。しかし、これを行うと、体を失います。

echo "Test message:\nThis is a line.\nAnd this is another." | nail joe@localhost

正常に動作しますが、主題はありません。

4

3 に答える 3

2

件名は最後の行に表示されるため、すべての行をバッファリングする必要があります(そうしないと、どの行が最後の行であるかを判断する方法がありません)。最初の行に件名を含める方がはるかに簡単です。なんでもいい。mapfileこれは、bash4.0で登場したものを使用した可能なアプローチです。

printf "%s\n" "Line one in the body of message" "Line two in the body of message" "Subject in the last line" | {
    mapfile -t array
    nail -s "${array[@]: -1}" joe@localhost < <(printf "%s\n" "${array[@]:0:${#array[@]}-1}")
}

最初の行に件名が必要だと判断した場合は、はるかに簡単です(もちろん、件名以外に無関係なサブシェルやバッファリングはありません)。

printf "%s\n" "Subject in the first line" "Line one in the body of message" "Line two in the body of message"  | { read -r subject; nail -s "$subject" joe@localhost; }
于 2013-01-02T12:00:53.360 に答える
2

名前付きパイプでそれを行うことができます、これはここで機能します:

mkfifo subj.fifo

echo "Test message:\nThis is a line.\nAnd this is another." |
  tee >(tail -n1 > subj.fifo) | mail -s "$(< subj.fifo)" joe@localhost

rm subj.fifo

テールの代わりにヘッドを使用する場合は、信号をtee無視する必要があることに注意してください。SIGPIPEtrap '' PIPE

于 2013-01-02T11:57:51.797 に答える
1

tail最後の前の行を破棄します。一時ファイルを使用することも、件名を最後ではなく最初に置くこともできます。いずれにせよ、協力プログラムがなければ、パイプがラインを消費し、維持する方法はありませんtee

#!/bin/sh
# use first line as subject, args are recipients
# stdin is message body
read subj
( echo "$subj"; cat ) | nail -s "$subj" "$@"
于 2013-01-02T11:41:01.740 に答える