2012-01-12 12 views
6

可能性の重複:
Capturing multiple line output to a bash variableシェルスクリプト、変数に格納するコマンドの出力および保存

私はおそらく基本的なスクリプトの質問で何を持っているが、私はすることができませんでした私が見たどこでも答えを見つけてください。

ファイルを処理するawkスクリプトがあり、無効なシステムのリストが吐き出されています。私は、コマンドラインから手動で呼び出すと、私は戻ってフォーマットされた出力を得る:

$awk -f awkscript datafile 

The following notifications are currently disabled: 

host: bar 
host: foo 

私は、私のcrontabから呼び出すためにawkスクリプトを実行する、任意の出力があるかどうかを決定ラッパースクリプトを書いていますし、メールがある場合は私にメールしてください。この方法を実行し、スクリプトにecho $BODYを追加することによって確認された場合、出力は(改行は、私はと心配です何を主にしている)の書式を剥奪され

BODY=`awk -f awkscript datafile` 
if [ -n "$BODY" ] 
then 
echo $BODY | mailx -s "Disabled notifications" [email protected] 
else 
echo "Nothing is disabled" 
fi 

ので、私:それは(簡体字)のように見えます

The following notitifications are currently disabled: host: bar host: foo 

私は手動でコマンドを実行すると、現在の書式を保持する方法を理解しようとしています。

物事私がこれまで試した:

echo -e `cat datafile | awkscript` > /tmp/tmpfile 
echo -e /tmp/tmpfile 

は、私は、\ nのような標準的なエスケープシーケンスを無視-eせずにエコーを使用して、私のためのシステム(Solarisの5.10)に、この試みました。うまくいきませんでした。私はtmpfileをチェックし、その中に何も書式を設定していないので、出力を保存するときに問題が発生しています。

BODY="$(awk -f awkscript datafile)" 
echo -e "$BODY" 

ここStackOverflowの上のいくつかの他の質問を含め、私が見つけることができるすべてが、問題は、それが引用されていなかった場合、シェルはスペースで空白のコードに置き換えるというものであったと言ったので、私はこれを試してみました。うまくいきませんでした。

私は、 `command`の代わりに$(command)を使用し、出力を保存するために変数の代わりに一時ファイルを使用して、エコーの代わりにprintfを使用しようとしましたが、何もフォーマットを保持していないようです。

私は何が欠けているのですか、またはこの問題をすべて回避する別の方法がありますか?引用符を使用して

+0

出力ファイルを使用していませんか? – fge

+0

出力をstdoutに出力するのではなく、出力ファイルを生成するawkスクリプトがありますか?私はちょうどそれに関わるものを調査していた。私はawkの印刷アクションをファイルにリダイレクトできることを知っています。私はclobberの代わりにappendをチェックするだけです。 – Madasi

+0

'>'の代わりにシェルから '>>'を使ってファイルに追加することができます。 '>'本当にclobbersですが、 '>>'は追加します。 – fge

答えて

8
BODY=`awk -f awkscript datafile` 
if [ -n "$BODY" ] 
then echo "$BODY" | mailx -s "Disabled notifications" [email protected] 
else echo "Nothing is disabled" 
fi 

echoの二重引用符に注意してください。

あなたも、このバージョンを簡素化することができます。

echo -e `cat datafile | awkscript` > /tmp/tmpfile 
echo -e /tmp/tmpfile 

にちょうど:

tmpfile=/tmp/tmpfile.$$ 
awkscript > $tmpfile 
if [ -s $tmpfile ] 
then mailx -s "Disabled notifications" [email protected] < $tmpfile 
else echo "Nothing is disabled" 
fi 

バッククォートが便利(より良い$(cmd args)として書かれた)ですが、どこでも使用する必要はありません。

+0

$ BODYに値を格納するときに書式設定の損失が発生するため、最初の例は機能しません。私はこれを 'echo -e" $ BODY "を使ってテストしました。しかし、2番目と3番目の例は完全に機能します。私は、一時ファイルにリダイレクトをテストする際に間違いを犯しました(私のデバッグコードは間違った変数の値を表示しました)ので、これはうまくいきませんでした。これは私が実装しようとしている修正です。 – Madasi

+0

'echo -e'を使わないでください。 'echo'を使ってください! –

+0

私も同じことをやってみました。私のシステムでは-eなしでエコーを使うと\ nのようなエスケープシーケンスを無視して代わりにそれらを表示するので、私はデフォルトで-eを使っていました。おそらく、私がやっているSolarisのバージョンで稼働する人工物でしょう。しかし、テストするために 'echo $ BODY'と' echo -e $ BODY'という行を含めて値を見て、両方から同じフォーマットされていない結果を得ました。 – Madasi

3

は仕事、そして私のためにしなければならない:

$ cat test.sh 
#!/bin/bash -e 

BODY=`cat test.in` 
if [ -n "$BODY" ]; then 
     echo "$BODY" | mailx -s "test" username 
else 
     echo "Nothing" 
fi 

$ cat test.in 

The following notifications are currently disabled: 

host: bar 
host: foo 

$ ./test.sh 
$ 

そして、これは私に適切な形式の電子メールを送信します。

+0

私は自分のシステムでこれをテストしましたが、あなたが正しいとすれば、これは正しい形式の電子メールを与えます。 – Madasi

+0

中間ファイルは、出力用の一時ファイルであろうと、フォーマットされたtest.inであろうと、変数の値にcattedされたときにはフォーマットを保持しますが、stdout上のフォーマットされた出力は変数に直接置かれたときにはフォーマットを保持しません。 – Madasi

関連する問題