如果使用率超过10%,以下shell脚本将检查磁盘空间并将变量diskfull
更改为1
最后一个回显始终显示0
我在if子句中尝试了global diskfull=1
,但它没有用。
如果消耗的磁盘超过10%,如何将变量更改为1
?
#!/bin/sh
diskfull=0
ALERT=10
df -HP | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $1 }' | while read output;
do
#echo $output
usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 )
partition=$(echo $output | awk '{ print $2 }' )
if [ $usep -ge $ALERT ]; then
diskfull=1
exit
fi
done
echo $diskfull
答案 0 :(得分:5)
这是在管道中使用while
的副作用。有两种解决方法:
1)将while
循环及其使用的所有变量放在一个单独的范围内,如levislevis86所示
some | complicated | pipeline | {
while read line; do
foo=$( some calculation )
done
do_something_with $foo
}
# $foo not available here
2)如果您的shell允许,使用进程替换,您可以将管道的输出重定向到while循环的输入
while read line; do
foo=$( some calculation )}
done < <(some | complicated | pipeline)
do_something_with $foo
答案 1 :(得分:1)
使用管道时,外壳接缝使用子外壳来完成工作。由于这些子壳不知道$diskfull
,因此值永远不会改变。
请参阅: http://www.nucleardonkey.net/blog/2007/08/variable_scope_in_bash.html
我按如下方式修改了你的脚本。它适用于我,也应该适用于您的系统。
#!/bin/sh
diskfull=0
ALERT=10
stats=`df -HP | grep -vE '^Filesystem|tmpfs|cdrom|none|udev' | awk '{ print $5 "_" $1 }'`
for output in $stats
do
usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 )
partition=$(echo $output | sed s/.*_// )
#echo $partition - $usep
if [ $usep -le $ALERT ]; then
diskfull=1
break
fi
done
echo $diskfull
答案 2 :(得分:1)
@OP,使用外支撑或()
count=0
max=10
diskfull=0
df -HP | { while read disk b c d used e
do
if [ "$count" -gt 1 ];then
used=${used%?}
if [ "$used" -gt "$max" ];then
echo "overload: $disk, used: $used%"
diskfull=1
fi
fi
count=$(( count+1 ))
done
echo "diskfull: $diskfull"
}
答案 3 :(得分:0)
我认为你不能进入diskfull=1
行,因为如果你是,你根本就没有输出 - 下面的exit
行会退出脚本。
我不知道为什么这不起作用,但请注意awk可以处理剩下的工作:
diskfull=$(df -HP | grep -vE '^Filesystem|tmpfs|cdrom' | awk 'BEGIN { x = 0 } { if ($5 + 0 >= '$ALERT') { x = 1 } } END { print x }')
这样你就不需要while循环了。
答案 4 :(得分:0)
你可以用gawk这样做(不需要使用grep)。对于警报,您可以向root发送电子邮件。
threshold=10
df -HP | awk -v t="$threshold" -v msg="" 'NR>1 && $5+0 > t{
msg=msg $1" is "$5"\n"
}END{print msg}' | mail root
或检查是否有“msg”或不首先
threshold=10
result=$(df -HP | awk -v t="$threshold" -v msg="" 'NR>1 && $5+0 > t{
msg=msg $1" is "$5"\n"
}END{print msg}')
if [ -n "$result" ];then
echo "Overload"
echo "$result" | mail root
fi
答案 5 :(得分:0)
在这一行:
usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 )
没有必要使用cut
。你可以这样做:
usep=$(echo $output | awk -F% '{ print $1}' )
答案 6 :(得分:0)
为了处理bash循环中的变量作用域问题,可以将变量保存在一个临时文件中,然后cat
将其保存到变量中。这不是最聪明、最有效的解决方案,但它易于阅读和思考。
如果有人想尝试与 Glenn 的 solution 不同的东西,可以试试这个:
some | complicated | pipeline | {
while read line; do
foo=$( some calculation )
done
do_something_with $foo
echo $foo > foo.tmp
}
# $foo not available here
foo=$(cat foo.tmp)
# $foo available here. do anything with it
rm foo.tmp
请注意,仅当您有权限创建文件(或指定您有权限的目录的绝对路径)时才有效