管道中变量的范围
以下 shell 脚本将检查磁盘空间,如果使用率超过 10%,则将变量 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
The following shell scrip will check the disk space and change the variable diskfull
to 1
if the usage is more than 10%
The last echo always shows 0
I tried the global diskfull=1
in the if clause but it did not work.
How do I change the variable to 1
if the disk consumed is more than 10%?
#!/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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这是在管道中使用
while
的副作用。有两种解决方法:1) 将
while
循环及其使用的所有变量放在单独的作用域中,如 levislevis86 所示2) 如果您的 shell 允许,请使用进程替换您可以将管道的输出重定向到 while 循环的输入
This is a side-effect of using
while
in a pipeline. There are two workarounds:1) put the
while
loop and all the variables it uses in a separate scope as demonstrated by levislevis862) if your shell allows it, use process substitution and you can redirect the output of your pipeline to the input of the while loop
当使用管道时,外壳似乎使用子外壳来完成工作。由于这些子 shell 不知道
$diskfull
,因此该值永远不会更改。看:
https://gist.github.com/CMCDragonkai/0a66ba5e37c5d1746d8bc814b37d6e1d
我修改了您的脚本如下。它适用于我,也应该适用于您的系统。
When using pipes the shell seems to use sub-shells to do the work. As
$diskfull
is not known to these sub-shells the value is never changed.See:
https://gist.github.com/CMCDragonkai/0a66ba5e37c5d1746d8bc814b37d6e1d
I modified your script as follows. It works for me and should work on your system too.
@OP,使用外大括号或 ()
@OP, use an outer brace or ()
我认为您一定不会到达
diskfull=1
行,因为如果您到达了,您将根本不会得到任何输出 - 以下exit
行将退出脚本。我不知道为什么这不起作用,但请注意 awk 可以处理其余的工作:
这样您就不需要 while 循环。
I think you must not be getting to the
diskfull=1
line, because if you were, you would get no output at all-- the followingexit
line would exit the script.I don't know why this isn't working, but note that awk can handle the rest of the work:
This way you don't need the while loop.
你可以用 gawk 这样做(不需要使用 grep)。对于警报,您可以向 root 发送电子邮件。
或者先检查是否有“msg”
you can do it this way with gawk(no need to use grep). for alerts you can send email to root.
or check whether there is "msg" or not first
在这一行中:
没有必要使用
cut
。你可以这样做:In this line:
it's not necessary to use
cut
. You can do this:为了处理 bash 循环中的变量作用域问题,可以将变量保存在临时文件中,然后将其
cat
到变量中。这不是最聪明、最有效的解决方案,但它很容易阅读和思考。如果有人想尝试与 Glenn 不同的解决方案,可以尝试以下操作:
请注意,只有在您拥有权限的情况下才有效创建文件(或指定您有权限的目录的绝对路径)
To deal with variable scope problem in bash loop, one can save the variable in a temporary file and later
cat
it to variable. It's not the smartest and efficient solution but It's easy to read and think.If someone want to try something different than Glenn's solution, it can try this:
Please note, It's only valid if you have permission to create a file (or specify the absolute path to directory where you have permission)