0

この背後にある少しの歴史-nfsマウントがマウント解除されているかどうか、マウントが古くなっているかどうかを検出するためにnagiosプラグインを作成しようとしています。これは、問題が発生している場所です。

私が達成しようとしているのは、マウントが古くなっているかどうかを検出することです。私が回避しようとしている問題は、古いnfsハンドルが原因で、そのディレクトリに対するアクションがハングし、3〜4分後にタイムアウトになるという事実です。読み取りを使用してnfsマウントディレクトリ内のstatコマンドにタイムアウトを強制することで、その問題を回避できるはずです。

そこで、このスニペットをどこかで取得しました。これは、nfsクライアントのCLIから手動で実行すると完全に機能します(/ www / logs / fooは古いnfsマウントです)。

$ read -t 2 < <(stat -t /www/logs/foo/*); echo $?
1

このスニペットを次のようなスクリプトに組み込むと、問題が発生します(スニペットが添付され、最後に完全なスクリプトが添付されます)。

list_of_mounts=$(grep nfs /etc/fstab | grep -v ^# | awk '{print $2'} | xargs)
exitstatus $LINENO

for X in $list_of_mounts; do
    AM_I_EXCLUDED=`echo " $* " | grep " $X " -q; echo $?`
    if [ "$AM_I_EXCLUDED" -eq "0" ]; then
    echo "" >> /dev/null
    #check to see if mount is mounted according to /proc/mounts
    elif [ ! `grep --quiet "$X " /proc/mounts; echo $?` -eq 0 ]; then
        #mount is not mounted at all, add to list to remount
        remount_list=`echo $remount_list $X`;
    #now make sure its not stale
    elif [ ! "`read -t 2  < <(stat -t $X/*) ; echo $?`" -eq "0" ]; then
        stalemount_list=`echo $stalemount_list $X`
    fi

このエラーが発生します:

/usr/lib64/nagios/plugins/check_nfs_mounts.sh: command substitution: line 46: syntax error near unexpected token `<'
/usr/lib64/nagios/plugins/check_nfs_mounts.sh: command substitution: line 46: `read -t 2  < <( '
/usr/lib64/nagios/plugins/check_nfs_mounts.sh: command substitution: line 46: syntax error near unexpected token `)'
/usr/lib64/nagios/plugins/check_nfs_mounts.sh: command substitution: line 46: ` ) ; echo $?'
/usr/lib64/nagios/plugins/check_nfs_mounts.sh: line 46: [: stat -t /www/logs/foo/*: integer expression expected

「read- t2<<(stat -t $ X /)」の代わりに「read -t 2 <<< $(stat -t $ X /)」を使用することで構文エラーを回避できましたが、stat読み取り時のタイムアウトの恩恵を受けなくなり、元の問題に戻ります。

私は新しいソリューションを受け入れていますが、このシェルとスクリプトの違いを引き起こしている可能性のある動作についても興味があります。

完全なnagiosチェック:

#!/bin/bash

usage() {
    echo "
    Usage:
    check_nfs_mounts.sh
    It just works.
    Optional: include an argument to exclude that mount point
"
}
ok() {
        echo "OK - $*"; exit 0
        exit
}
warning() {
        echo "WARNING - $*"; exit 1
        exit
}
critical() {
        echo "CRITICAL - $*"; exit 2
        exit
}
unknown() {
        echo "UNKNOWN - $*"; exit 3
        exit
}
exitstatus() {
        if [ ! "$?" -eq "0" ] ;
        then unknown "Plugin failure - exit code not OK - error line $*"
        fi
}
# Get Mounts
list_of_mounts=$(grep nfs /etc/fstab | grep -v ^# | awk '{print $2'} | xargs)
exitstatus $LINENO

for X in $list_of_mounts; do
    AM_I_EXCLUDED=`echo " $* " | grep " $X " -q; echo $?`
    if [ "$AM_I_EXCLUDED" -eq "0" ]; then
    echo "" >> /dev/null
    #check to see if mount is mounted according to /proc/mounts
    elif [ ! `grep --quiet "$X " /proc/mounts; echo $?` -eq 0 ]; then
        #mount is not mounted at all, add to list to remount
        remount_list=`echo $remount_list $X`;
    #now make sure its not stale
    elif [ ! "`read -t 2  <<< $(stat -t $X/*) ; echo $?`" -eq "0" ]; then
        stalemount_list=`echo $stalemount_list $X`
    fi
done
#Make sure result is a number
if [ -n "$remount_list" ] && [ -n "$stalemount_list" ];  then
    critical "Not mounted: $remount_list , Stale mounts: $stalemount_list"
elif [ -n "$remount_list" ] && [ -z "$stalemount_list"]; then
    critical "Not mounted: $remount_list"
elif [ -n "$stalemount_list" ] && [ -n "$remount_list" ]; then
    critical "Stale mount: $stalemount_list"
elif [ -z "$stalemount_list" ] && [ -z "$remount_list" ]; then
    ok "All mounts mounted"
fi
4

2 に答える 2

1

シバンがBashを指定していることを確認する必要があります。

#!/bin/bash

エラーメッセージの理由は、システム上で、/bin/shシバンがない場合またはシバンがある場合に使用されるBashがシンボリックリンクされているため#!/bin/shです。

この場合、Bashは開始したかのように実行されプロセス置換()などのPOSIX以外の機能bash --posixは無効になりますが、ヒア文字列()などの他の機能は無効になります。<()<<<

シバンを変えれば大丈夫です。

于 2012-06-20T11:36:57.313 に答える
0

次の方法でサブシェルの出力を保存できます。

$ read a < <(echo one)
$ echo $a
one

またはこの方法で($ aを処理して忘れたい場合:

$ ( echo one; echo two) | (read a; echo $a)
one

最初のバリアントはでのみ機能しbashます。Bourne Shell(/bin/sh)はこの構文をサポートしていません。それがエラーメッセージが表示される理由かもしれません。あなたのスクリプトはによってで/bin/shはなくによって解釈されるかもしれません/bin/bash

于 2012-06-19T17:17:05.840 に答える