私は "高速"スクリプトを書いてから、メールスイッチ(エコーからパイプされる構文)をオフにするために "--nomail"オプションを追加することを検討しました。
私はそれが簡単だと思いましたが、基本的に元のスクリプトをうまく設定していないので、この「オプション」は私を殺しました。
Bashの新機能です...ありがとう!
私の素晴らしい仕事スクリプト! :
## Current threshold value setting
THRESHOLD="80"
## Input Files and Mailx
LOCATIONS="fsIn.txt" ## Edit "fsIn.txt" to add or change filesystems
TOLIST="$(cat toList.txt | tr -s '\n' ' ' )" ## Sets who receives email if an error condition exists
REPLYTO="$(cat replyTo.txt | tr -s '\n' ' ' )" ## sets the reply to email addresses
FROM=”SCRIPT TEAM" ## Sets the "from" address on error emails
SUBJECT="$HOST: ! STORAGE LEVEL MET OR EXCEEDED !" ## Sets the subject line
############
for i in $(cat $LOCATIONS)
do
## Main df pipeline to return usage percentage
CAP=$(df -PH --no-sync "$i" | awk 'NR>1'| awk {'print $5'} | sed 's/.$//')
for i in $(cat $LOCATIONS) #Several different file system locations are ‘catted’ in here . E.g. /dev
do
## Main df pipeline to return usage percentage to stdout and piped to mailx
CAP=$(df -PH --no-sync "$i" | awk 'NR>1'| awk {'print $5'} | sed 's/.$//')
if [ $CAP -ge $THRESHOLD ]
then
(echo
echo "---------- CAPACITY TEST FAILED ---------- "
echo -n " SYSTEM NAME: " ; uname -n
echo -n " USER DETAIL: " ; whoami
echo " TEST AREA: $i "
echo " USED SPACE: $CAP% "
echo " THRESHOLD: $THRESHOLD% "
echo " !!!!!! THRESHOLD EXCEEDED !!!!!! ") | tee >(mailx -s "$SUBJECT" -r "$FROM" -S replyto="$REPLYTO" "$TOLIST")
echo
else
echo
echo "++++++++++ CAPACITY TEST PASSED ++++++++++ "
echo " TEST AREA: $i "
echo " USED SPACE: $CAP% "
echo " THRESHOLD: $THRESHOLD% "
echo " !!! SUCCESS SUCCESS SUCCESS SUCCESS !!! "
echo
fi
done
exit 0
これは非常にうまく動作します!しかし、--nomailオプションを含めるように再設定する方法がわかりません。 「事例」は慎重だと思われますが、ここでは迷子になりました。
どんなアイデアがありますか?
とても感謝しています!
答え1
簡単な答えは2つあります。
send_email
toなどのフラグを設定し、true
電子メール抑制パラメータがある場合は、それを無効にするか、falseに設定します。- 出力になる変数または一時ファイルを組み合わせてから、実際の電子メール転送を関数呼び出しに渡して事前に電子メールを作成します。
たとえば、
send_email="true"
handle_email() {
echo "$email_body" | mailx -s "$subject" -r "$from" -S replyto="$replyto" ${recipients[@]}
}
[...]
if [[ "--nomail" == "$1" ]]; then
send_email=false
fi
[...]
if [[ true == "$send_email ]]; then
handle_email
fi
答え2
修正する
私は戻ってあなたの質問全体を読んで、もともとあなたが要求したものとは少し異なる質問に答えたことに気づきました。だからここにあります:
あなたの構造は素晴らしいです。スクリプトの先頭でコマンドオプションを解析します。
case
はい、ステートメントを使用して確認できます$1
(下記の元の回答を参照)。ただし、1つのオプションのみを計画している場合は、単一のテストを簡単に実行できます(下記の元の回答を参照)。case
いくつかの可能なオプションを含むステートメントを使用するには、そのコマンドをwhile
コマンドラインの次の単語/オプションに置き換えます。while "$1" ; do case ... esac; shift; done
shift
$1
元の答え
この問題を解決する方法はいくつかあります。これが唯一のオプションである場合、またはいくつかのオプションがある場合は、手動で手動で解析することを検討できます。シェル言語では、シェルコマンドの後に続くすべての単語をシェルと呼びます。パラメータ、そしてそれぞれ位置パラメータ、フォームは1$n
から始まりますn
。したがって、テストを実行して問題が発生していることを確認し、[[ $1 == "--nomail" ]]
それに応じて対処することができます。これはオプションが1つしかないシンプルで簡単な方法です。
getopts
オプションが多いより複雑なシェルスクリプトの場合は、特定の形式のコマンドを使用してオプションを解析する必要があるかもしれません。シェルには組み込みバージョンがbash
含まれており、コマンドラインにthen(デフォルトのポケットベルが設定されている場合)を入力して詳細を確認できます。getopts
man bash
less
/^ *getopt
答え3
他の回答では、すでにコマンドラインオプションを使用する方法について言及しています(つまり、"$1"
直接確認または使用getopts
)。私の答えは、--nomail
スクリプトを最初から書き直さずにオプションを使用するようにスクリプトをすばやく変更する方法です。シェルスクリプティング技術と知識の進歩的な向上を活用するには、長期的にこれを行う必要があります。
最も明白な方法は、変数または一時ファイルを使用して印刷したい出力を保存または印刷してメールに送信し、それを毎回処理する方法を選択することです。
あまり明白ではない方法は、パイプを標準入力か、単に入力かをtee >(mailx ...)
決定する関数呼び出しのパイプに置き換えることです。このアプローチでは、出力を保存する必要はなく、出力をパイプして関数が処理するようにします。残りのコードは知ったり気にする必要はありません(そして最も重要なことは処理するために書く必要はありません)。どちらの場合も)。tee
mailx
cat
それはすべて...
まず、スクリプトの先頭の近くに次のコードを追加します。
# set the default, i.e. to send mail.
send_email=1
# Very basic option processing. Using getopts would be better.
[ "$1" == "--nomail" ] && send_email=''
myoutput() {
if [ "$send_email" ] ; then
# print stdin to stdout AND mail it
tee <(mailx -s "$SUBJECT" -r "$FROM" -S replyto="$REPLYTO" "$TOLIST")
else
# only print stdin to stdout. no mail.
cat
fi
}
次に、| tee ...
ループ内で置き換えて、ここで定義された関数を使用します。for
| myoutput
(myoutput
不都合な関数名です。名前を変更するcat_or_mail
か、最も理解しやすい名前に変更してください。)
理想的には、関数はグローバル変数に依存するのではなくパラメータを受け入れる必要があり、次のように書く必要があります。
myoutput() {
local send_email SUBJECT FROM REPYLTO TOLIST
# more of the primitive option handling. getopts can and should be used
# inside a function too.
send_email="$1"
SUBJECT="$2"
FROM="$3"
REPLYTO="$4"
TOLIST="$5"
# add code here to check if those variables contain valid values.
# print warnings and/or abort and/or set appropriate defaults if they don't.
if [ "$send_email" ] ; then
# print stdin to stdout AND mail it
tee <(mailx -s "$SUBJECT" -r "$FROM" -S replyto="$REPLYTO" "$TOLIST")
else
# only print stdin to stdout. no mail.
cat
fi
}
そして電話してください... | myoutput "$send_email" "$SUBJECT" "$FROM" "$REPLYTO" "$TOLIST"
これにより、グローバル変数を事前設定しなくても関数を再利用できます。必要な値で呼び出すだけです。