编辑:下面的工作脚本
我已经多次使用这个网站来获得答案,但我对此感到有点难过。
我的任务是在bash中编写一个脚本来登录大约2000个Unix服务器(Solaris,AIX,Linux)并检查OS文件系统的大小,最值得注意的是/ var / usr / opt。
我已经设置了一些变量,这可能是我马上出错的地方。
1。)首先,我连接到另一台服务器,该服务器包含基础架构中所有主机的列表。然后我用一些sed命令解析这些数据,以获得一个我可以正确使用的列表
1。)然后我进行ping测试,看看服务器是否还活着。如果服务器是decom。这背后的想法是,如果服务器不可ping,我不希望它被报告,或任何尝试连接到它,因为它只是浪费时间。我觉得我做错了,但不知道如何做到这一点(你将在这篇文章中重新出现的主题大声笑)
如果任何FS超过80%标记,那么它应该输出到文本文件,其中servername,filesystem,size在一行< == 对我来说非常重要
如果FS低于80%,那么我不想在输出中使用它,它可以完全省略。
我已经创建了一些我将在下面发布的内容,我希望能找到一些帮助来弄清楚我哪里出错了。我是一个非常新的bash脚本,但有作为Unix管理员的经验(我从来不擅长脚本)。
任何人都可以提供指导并告诉我哪里出错了吗?
我将上传我可以确认明天有效的脚本。感谢大家对此的投入!
答案 0 :(得分:0)
有些麻烦在这里:
ping -c 1 -W 3 $i > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "$i is offline" >> $LOG
fi
如果你需要continue
声明。您的程序并不是以不同方式处理不可ping的主机,只是记录它们不能ping通。
好的,现在我看起来更深一点,而且这里有更天真的东西。这些不应该起作用:
SOLVARFS=$(df -h /var |cut -f5 |grep -v capacity |awk '{print $5}')
SOLUSRFS=$(df -h /usr |cut -f5 |grep -v capacity |awk '{print $5}')
SOLOPTFS=$(df -h /opt |cut -f5 |grep -v capacity |awk '{print $5}')
etc...
这些行的问题是,在ssh
会话发生之前,命令替换被分配给变量。因此,每个变量的内容是命令在本地系统上的结果,而不是命令本身。由于您在ssh
次调用周围进行了命令替换,因此将这些行重写为(注意$5
上的反斜杠转义)可能会很有效:
SOLVARFS="df -h /var |cut -f5 |grep -v capacity |awk '{print \$5}'"
SOLUSRFS="df -h /usr |cut -f5 |grep -v capacity |awk '{print \$5}'"
SOLOPTFS="df -h /opt |cut -f5 |grep -v capacity |awk '{print \$5}'"
etc...
您与其他服务器联系的部分还有一些需要更正的内容。每个服务器不需要三个if语句,并且没有理由向/dev/null
回应任何内容。这是SunOS部分的重写。对于您要检查的每个目录,它会输出主机名,命令名(以便您可以查看正在检查的目录)以及结果:
if [[ $UNAME = "SunOS" ]]; then
for SSH_COMMAND in SOLVARFS SOLUSRFS SOLOPTFS ; do
RESULT=`ssh -o PasswordAuthentication=no -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=2 GSSAPIAuthentication=no -q $i ${!SSH_COMMAND}`
if ["$RESULT" -gt 80] ; do
echo "$i, $SSH_COMMAND, $RESULT" >> $LOG
fi
done
fi
请注意,${!BLAH}
构造是变量间接的。 "给我BLAH"。
答案 1 :(得分:0)
这是我的“磁盘使用情况”linux脚本,希望能帮到你。
#!/bin/sh
df -H | awk '{ print $5 " " $6 }' | while read output;
do
echo $output
usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 )
partition=$(echo $output | awk '{ print $2 }' )
if [ $usep -ge 90 ]; then
echo "Running out of space \"$partition ($usep%)\" on $(hostname) as on $(date)" |
mail -s "Warning! There is no space on the disk: $usep%" root@domain.com
fi
done
答案 2 :(得分:0)
你的原始脚本做了一些不太理想的事情。不是为每个文件系统和每个操作系统运行几乎完全相同的代码块,而是要以一段代码可以迭代所有对象的方式记录差异,并根据需要进行调整。
这是我对此的看法。命令应该出现在ONCE,但是
以下脚本通过lint检查,但显然这是未经测试的,因为我没有要测试的环境。 您可能仍想考虑日志记录和通知的工作方式。
#!/bin/bash
# Assign temp file, remove it automatically upon successful exit.
tmpfile=$(mktemp /tmp/${0##*/}.XXXX)
trap "rm '$tmpfile'" 0
#NOW=$(date +"%Y-%m-%d-%T")
NOW=$(date +"%F")
LOG=/usr/scripts/disk_usage/Unix_df_issues-$NOW.txt
printf '' > "$LOG"
# Use variables to refer to commonly accessed files. If you change a name, just do it once.
rawhostlist=all_vms.txt
host_os=${rawhostlist}_OS
# Commonly-used options need only be declared once. Use an array for easier management.
declare -a ssh_opts=()
ssh_opts+=(-o PasswordAuthentication=no)
ssh_opts+=(-o BatchMode=yes)
ssh_opts+=(-o StrictHostKeyChecking=no) # Eliminate prompts on new hosts
ssh_opts+=(-o ConnectTimeout=2) # This should make your `ping` unnecessary.
ssh_opts+=(-o GSSAPIAuthentication=no) # This is default. Do we really need it?
# Note: Associative arrays require Bash 4.x.
declare -A df_opts=(
[SunOS]="-h"
[Linux]="-hP"
[AIX]=""
)
declare -A df_column=(
[SunOS]=5
[Linux]=5
[AIX]=4
)
# Fetch host list from configserver, stripping /^adm/ on the remote end.
ssh "${ssh_opts[@]}" -q configserver "sed 's/^adm//' /reports/*/HOSTNAME" > "$rawhostlist"
# Confirm that our host_os cache is up to date and process any missing hosts.
awk '
NR==FNR { h[$1]; next } # Add everything in rawhostlist to an array...
{ delete h[$1] } # Then remove any entries that exist in host_os.
END {
for (i in h) print i # And print whatever remains.
}' "$rawhostlist" "$host_os" |
while read h; do
printf '%s\t%s\n' "$h" $(ssh "$h" "${ssh_opts[@]}" -q uname -s)
done >> "$host_os"
# Next, step through the host list and collect data.
while read host os; do
ssh "${ssh_opts[@]}" "$host" df "${df_opts[$os]}" /var /usr /opt |
awk -v column="${df_column[$os]}" -v host="$host" 'NR>1 { print host,$1,$column }'
)
done < "$host_os" > "$tmpfile"
# Now that we have all our data, check for warning/critical levels.
while read host filesystem usage; do
if [ "$usage" -gt 80 ]; then
status="CRITICAL"
elif [ "$usage" -gt 70 ]; then
status="WARNING"
else
continue
fi
# Log our results to our log file, AND send them to stderr.
printf "[%s] %s: %s:%s at %d%%\n" "$(date +"%F %T")" "$status" "$host" "$filesystem" "$usage" | tee -a "$LOG" >&2
done < "$tmpfile"
# Email and record our results.
if [ -s "$LOG" ]; then
mail -s "Daily Unix /var Report - $NOW" unixsystems@examplle.com < "$LOG"
mv "$LOG" /var/log/vm_reports/
fi
考虑这个示例代码。如果您喜欢它的外观,那么您的下一个任务就是调试它,或者为您调试时遇到问题的部分打开新问题。 : - )