Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 用于查找文件系统使用情况的Bash脚本_Linux_Bash_Shell_Solaris_Redhat - Fatal编程技术网

Linux 用于查找文件系统使用情况的Bash脚本

Linux 用于查找文件系统使用情况的Bash脚本,linux,bash,shell,solaris,redhat,Linux,Bash,Shell,Solaris,Redhat,编辑:下面的工作脚本 我已经使用这个网站很多次,以获得答案,但我有点困惑这一点 我的任务是在bash中编写一个脚本,登录大约2000台Unix服务器(Solaris、AIX、Linux),并检查操作系统文件系统的大小,最著名的是/var/usr/opt 我设置了一些变量,这可能是我一开始就出错的地方 1.)首先,我连接到另一台服务器,该服务器具有基础结构中所有主机的列表。然后,我用一些sed命令解析这些数据,以得到一个可以正确使用的列表 1.)然后我进行ping测试,以查看服务器是否处于活动状态

编辑:下面的工作脚本

我已经使用这个网站很多次,以获得答案,但我有点困惑这一点

我的任务是在bash中编写一个脚本,登录大约2000台Unix服务器(Solaris、AIX、Linux),并检查操作系统文件系统的大小,最著名的是/var/usr/opt

我设置了一些变量,这可能是我一开始就出错的地方

1.)首先,我连接到另一台服务器,该服务器具有基础结构中所有主机的列表。然后,我用一些sed命令解析这些数据,以得到一个可以正确使用的列表

1.)然后我进行ping测试,以查看服务器是否处于活动状态。如果服务器是decom。这背后的想法是,如果服务器无法ping,我不希望报告它,也不希望尝试连接到它,因为这只是浪费时间。我觉得我做错了,但不知道如何正确地去做(这是一个重复出现的主题,你会在这篇文章中lol)

如果任何FS超过80%标记,那么它应该输出到一个文本文件,其中一行包含服务器名、文件系统、大小一些问题如下:

ping -c 1 -W 3 $i > /dev/null 2>&1
    if [ $? -ne 0 ]; then
            echo "$i is offline" >> $LOG
    fi
您需要在if中包含一个
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
上的反斜杠转义):

您联系另一个服务器的部分还有一些需要更正的内容。每个服务器不需要三条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命名的变量的内容”。

这是我的“磁盘使用”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

您的原始脚本做了很多事情,但没有达到最佳效果。与其为每个文件系统和每个操作系统运行几乎相同的代码块,不如用一段代码可以迭代所有对象的方式记录差异,并根据需要进行调整

这是我的看法。命令应该出现一次,但是

  • 它们通过循环多次运行
  • 它们使用数组以多种方式运行
下面的脚本通过了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
#/bin/bash
#分配临时文件,成功退出后自动将其删除。
tmpfile=$(mktemp/tmp/${0##*/}.XXXX)
陷阱“rm'$tmpfile'”0
#现在=$(日期+%Y-%m-%d-%T)
现在=$(日期+%F)
LOG=/usr/scripts/disk\u usage/Unix\u df\u issues-$NOW.txt
printf“”>“$LOG”
#使用变量引用通常访问的文件。如果你改了一个名字,就改一次。
rawhostlist=all_vms.txt
host_os=${rawhostlist}\u os
#常用选项只需声明一次。使用阵列以便于管理。
declare-a ssh_opts=()
ssh_opts+=(-o PasswordAuthentication=no)
ssh_opts+=(-o BatchMode=yes)
ssh_opts+=(-o StrictHostKeyChecking=no)#消除新主机上的提示
ssh_opts+=(-o ConnectTimeout=2)#这会使您的“ping”变得不必要。
ssh_opts+=(-o GSSAPIAuthentication=no)#这是默认值。我们真的需要它吗?
#注意:关联数组需要Bash 4.x。
声明-A df_选项=(
[SunOS]=“-h”
[Linux]=“-hP”
[AIX]=“”
)
declare-A df_列=(
[SunOS]=5
[Linux]=5
[AIX]=4
)
#从configserver获取主机列表,在远程端剥离/^adm/。
ssh“${ssh_opts[@]}”-q configserver“sed的/^adm/'/reports/*/HOSTNAME”>“$rawhostlist”
#确认我们的主机操作系统缓存是最新的,并处理任何丢失的主机。
awk'
NR==FNR{h[$1];next}#将rawhostlist中的所有内容添加到数组中。。。
{delete h[$1]}#然后删除主机操作系统中存在的所有条目。
结束{
对于(h中的i)打印i#并打印剩余的内容。
}“$rawhostlist”“$host_os”|
读h;做
printf“%s\t%s\n'$h”$(ssh“$h”“${ssh_opts[@]}”-q uname-s)
完成>>“$host_os”
#接下来,逐步浏览主机列表并收集数据。
同时读取主机操作系统;做
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}”
)
完成<“$host_os”>“$tmpfile”
#现在我们有了所有数据,检查警告/严重级别。
同时读取主机文件系统的使用情况;做
如果[“$usage”-gt 80];然后
status=“严重”
elif[“$使用量”-gt 70];然后
status=“警告”
其他的
持续
fi
#将结果记录到日志文件中,并将其发送到stderr。
printf“[%s]%s:%s:%s位于%d%%\n”“$(日期+%F%T”)”“$status”“$host”“$filesystem”“$usage”| tee-a“$LOG”>&2
完成<“$tmpfile”
#发送电子邮件并记录我们的结果。
如果[-s“$LOG”];然后
mail-s“每日Unix/var报告-$NOW”unixsystems@examplle.com<“$LOG”
mv“$LOG”/var/LOG/vm_报告/
fi

考虑这个示例代码。如果您喜欢它的外观,您的下一个任务就是调试它,或者为调试有困难的部分提出新问题。:-)

如果我在一个窗口中运行脚本,并在另一个窗口中跟踪输出文件,我可以在输出文件中看到不可ping的服务器出现在其中。但是,a.)处于活动状态(b.)的服务器中没有一个具有超过80%appe的FS
#!/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