这背后的一点历史 - 我正在尝试编写一个nagios插件来检测是否已卸载nfs挂载以及挂载是否过时,这是我遇到问题的地方。
我想要实现的是检测装载是否陈旧。我正在努力解决的问题是,陈旧的nfs句柄导致该目录上的任何操作挂起并在3-4分钟后超时。通过使用read强制超时到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 -t 2&lt;&lt;&lt; $(stat -t $ X / )”而不是“read -t 2&lt;&lt;(stat - )来解决语法错误。 t $ X / )“,但是stat不再受益于读取超时,这使我回到原来的问题。
虽然我对新的解决方案持开放态度,但我也很好奇可能导致这种shell与脚本差异的行为。
完整的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
答案 0 :(得分:1)
你需要确保你的shebang指定Bash:
#!/bin/bash
错误消息的原因是在您的系统上,Bash符号链接到/bin/sh
,当没有shebang或#!/bin/sh
时使用。{/ p>
在这种情况下,Bash的运行就像你使用bash --posix
启动它一样,它会禁用某些非POSIX功能,例如进程替换(<()
),但会令人困惑不是其他如此字符串(<<<
)。
改变你的shebang,你应该没事。
答案 1 :(得分:0)
您可以这种方式保存子shell的输出:
$ 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