`
jinghong
  • 浏览: 55565 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

linux系统获取基础硬件信息的shell

阅读更多
来自http://code.google.com/p/aspersa/

#!/bin/sh
# This program is part of Aspersa (http://code.google.com/p/aspersa/)

# ########################################################################
# A script to summarize system information in a nice way.
# Goals: work well on Linux; create a compact diff-able report that is
# easy to paste into a wiki or email, and easy to scan and compare too.
#
# Usage: $ wget -O- http://aspersa.googlecode.com/svn/trunk/summary |bash
# Options are set through the ASPERSA_SKIP environment variable.  Set this
# variable to a comma-separated list of things you want to omit.
# Options:
#  MOUNT:   Don't print out mounted filesystems and disk fullness.
#  NETWORK: Don't print out information on network controllers & config.
#  PROCESS: Don't print out top processes and vmstat information.
#
# Authors:
#  Baron Schwartz
#  Kevin van Zonneveld (kvz@php.net || http://kevin.vanzonneveld.net)
# ########################################################################

# ########################################################################
# Globals, settings, helper functions
# ########################################################################
POSIXLY_CORRECT=1
export POSIXLY_CORRECT

# The awk code for fuzzy rounding.  (It's used in a few places, so makes sense
# not to duplicate).  It fuzzy-rounds the variable named fuzzy_var.  It goes in
# steps of 5, 10, 25, then repeats by a factor of 10 larger (50, 100, 250), and
# so on, until it finds a number that's large enough.  The pattern is slightly
# broken between the initial 1 and 50, because rounding to the nearest 2.5
# doesn't seem right to me.
fuzzy_formula='
   rounded = 0;
   if (fuzzy_var <= 10 ) {
      rounded   = 1;
   }
   factor = 1;
   while ( rounded == 0 ) {
      if ( fuzzy_var <= 50 * factor ) {
         fuzzy_var = sprintf("%.0f", fuzzy_var / (5 * factor)) * 5 * factor;
         rounded   = 1;
      }
      else if ( fuzzy_var <= 100  * factor) {
         fuzzy_var = sprintf("%.0f", fuzzy_var / (10 * factor)) * 10 * factor;
         rounded   = 1;
      }
      else if ( fuzzy_var <= 250  * factor) {
         fuzzy_var = sprintf("%.0f", fuzzy_var / (25 * factor)) * 25 * factor;
         rounded   = 1;
      }
      factor = factor * 10;
   }'

# Does fuzzy rounding: rounds to nearest interval, but the interval gets larger
# as the number gets larger.  This is to make things easier to diff.
fuzz () {
   echo $1 | $AP_AWK "{fuzzy_var=\$1; ${fuzzy_formula} print fuzzy_var;}"
}

# The temp files are for storing working results so we don't call commands many
# times (gives inconsistent results, maybe adds load on things I don't want to
# such as RAID controllers).  They must not exist -- if they did, someone would
# symlink them to /etc/passwd and then run this program as root.  Call this
# function with "rm" or "touch" as an argument.
temp_files() {
   for file in /tmp/aspersa /tmp/aspersa2; do
      case "$1" in
      touch)
         if ! touch "${file}"; then
            echo "I can't make my temp file ${file}";
            exit 1;
         fi
         ;;
      rm)
         rm -f "${file}"
         ;;
      esac
   done
}

# Print a space-padded string into $line.  Then translate spaces to hashes, and
# underscores to spaces.  End result is a line of hashes with words at the
# start.
section () {
   echo "$1" | awk '{l=sprintf("#_%-60s", $0 "_"); print l}' | sed -e 's/ /#/g' -e 's/_/ /g'
}

# Print a "name | value" line.
name_val() {
   printf "%12s | %s\n" "$1" "$(echo $2)"
}

# Converts a value to units of power of 2.  Arg 1: the value.  Arg 2: precision (defaults to 2).
shorten() {
   echo $@ | awk '{
      unit = "k";
      size = 1024;
      val  = $1;
      prec = 2;
      if ( $2 ~ /./ ) {
         prec = $2;
      }
      if ( val >= 1099511627776 ) {
         size = 1099511627776;
         unit = "T";
      }
      else if ( val >= 1073741824 ) {
         size = 1073741824;
         unit = "G";
      }
      else if ( val >= 1048576 ) {
         size = 1048576;
         unit = "M";
      }
      printf "%." prec "f%s", val / size, unit;
   }'
}

# ##############################################################################
# Function to take a file and collapse it into an aggregated list.  This
# function works on $1, which it expects to be created with 'sort |
# uniq -c'.  Leading whitespace is deleted.  The result will look like
# "4xabc, 1xdef"  Copy any changes to 'mysql-summary' too.
# ##############################################################################
group_concat () {
   sed -e '{H; $!d}' -e 'x' -e 's/\n[[:space:]]*\([[:digit:]]*\)[[:space:]]*/, \1x/g' -e 's/[[:space:]][[:space:]]*/ /g' -e 's/, //' ${1}
   # In words: save the whole file into the hold space,
   # {H; $!d}
   # Swap it back into the pattern space,
   # x
   # Join lines with a comma, delete leading whitespace, and put an 'x' between
   # the number and the text that follows,
   # s/\n[[:space:]]*\([[:digit:]]*\)[[:space:]]*/, \1x/g
   # Collapse whitespace,
   # s/[[:space:]][[:space:]]*/ /g
   # And delete the leading comma-space.
   # s/, //
}

# ##############################################################################
# Functions for parsing specific files and getting desired info from them.
# These are called from within main() and are separated so they can be tested
# easily.  The calling convention is that the data they need to run is prepared
# first by putting it into /tmp/aspersa.  Then code that's testing just needs to
# put sample data into /tmp/aspersa and call it.
# ##############################################################################
   
# ##############################################################################
# Parse Linux's /proc/cpuinfo, which should be stored in /tmp/aspersa.
# ##############################################################################
parse_proc_cpuinfo () {
   # Physical processors are indicated by distinct 'physical id'.  Virtual CPUs
   # are indicated by paragraphs -- one per paragraph.  We assume that all
   # processors are identical, i.e. that there are not some processors with dual
   # cores and some with quad cores.
   virtual=$(grep -c ^processor /tmp/aspersa);
   physical=$(grep 'physical id' /tmp/aspersa | sort -u | wc -l);
   cores=$(grep 'cpu cores' /tmp/aspersa | head -n 1 | cut -d: -f2);

   # Older kernel won't have 'physical id' or 'cpu cores'.
   if [ "${physical}" = "0" ]; then physical=${virtual}; fi
   if [ -z "${cores}" ]; then cores=0; fi

   # Test for HTT; cannot trust the 'ht' flag.  If physical * cores < virtual,
   # then hyperthreading is in use.
   cores=$((${cores} * ${physical}));
   if [ ${cores} -gt 0 -a $cores -lt $virtual ]; then htt=yes; else htt=no; fi

   name_val "Processors" "physical = ${physical}, cores = ${cores}, virtual = ${virtual}, hyperthreading = ${htt}"

   awk -F: '/cpu MHz/{print $2}' /tmp/aspersa \
      | sort | uniq -c > /tmp/aspersa2
   name_val "Speeds" "$(group_concat /tmp/aspersa2)"

   awk -F: '/model name/{print $2}' /tmp/aspersa \
      | sort | uniq -c > /tmp/aspersa2
   name_val "Models" "$(group_concat /tmp/aspersa2)"

   awk -F: '/cache size/{print $2}' /tmp/aspersa \
      | sort | uniq -c > /tmp/aspersa2
   name_val "Caches" "$(group_concat /tmp/aspersa2)"
}

# ##############################################################################
# Parse sysctl -a output on FreeBSD, and format it as CPU info.  The file is the
# first argument.
# ##############################################################################
parse_sysctl_cpu_freebsd() {
   virtual="$(awk '/hw.ncpu/{print $2}' "$1")"
   name_val "Processors" "virtual = ${virtual}"
   name_val "Speeds" "$(awk '/hw.clockrate/{print $2}' "$1")"
   name_val "Models" "$(awk -F: '/hw.model/{print substr($2, 2)}' "$1")"
}

# ##############################################################################
# Parse CPU info from psrinfo -v
# ##############################################################################
parse_psrinfo_cpus() {
   name_val Processors $(grep -c 'Status of .* processor' "$1")
   awk '/operates at/ {
      start = index($0, " at ") + 4;
      end   = length($0) - start - 4
      print substr($0, start, end);
   }' "$1" | sort | uniq -c > /tmp/aspersa2
   name_val "Speeds" "$(group_concat /tmp/aspersa2)"
}

# ##############################################################################
# Parse the output of 'free -b' plus the contents of /proc/meminfo
# ##############################################################################
parse_free_minus_b () {
   physical=$(awk '/Mem:/{print $3}' "${1}")
   swap=$(awk '/Swap:/{print $3}' "${1}")
   virtual=$(shorten $(($physical + $swap)))

   name_val Total   $(shorten $(awk '/Mem:/{print $2}' "${1}"))
   name_val Free    $(shorten $(awk '/Mem:/{print $4}' "${1}"))
   name_val Used    "physical = $(shorten ${physical}), swap = $(shorten ${swap}), virtual = ${virtual}"
   name_val Buffers $(shorten $(awk '/Mem:/{print $6}' "${1}"))
   name_val Caches  $(shorten $(awk '/Mem:/{print $7}' "${1}"))
   name_val Dirty  "$(awk '/Dirty:/ {print $2, $3}' "${1}")"
}

# ##############################################################################
# Parse FreeBSD memory info from sysctl output.
# ##############################################################################
parse_memory_sysctl_freebsd() {
   physical=$(awk '/hw.realmem:/{print $2}' "${1}")
   mem_hw=$(awk '/hw.physmem:/{print $2}' "${1}")
   mem_used=$(awk '
      /hw.physmem/                   { mem_hw       = $2; }
      /vm.stats.vm.v_inactive_count/ { mem_inactive = $2; }
      /vm.stats.vm.v_cache_count/    { mem_cache    = $2; }
      /vm.stats.vm.v_free_count/     { mem_free     = $2; }
      /hw.pagesize/                  { pagesize     = $2; }
      END {
         mem_inactive *= pagesize;
         mem_cache    *= pagesize;
         mem_free     *= pagesize;
         print mem_hw - mem_inactive - mem_cache - mem_free;
      }
   ' "$1");
   name_val Total   $(shorten ${mem_hw} 1)
   name_val Virtual $(shorten ${physical} 1)
   name_val Used    $(shorten ${mem_used} 1)
}

# ##############################################################################
# Parse memory devices from the output of 'dmidecode', which should be stored in
# /tmp/aspersa.
# ##############################################################################
parse_dmidecode_mem_devices () {
   echo "  Locator   Size     Speed             Form Factor   Type          Type Detail"
   echo "  ========= ======== ================= ============= ============= ==========="
   # Print paragraphs containing 'Memory Device\n', extract the desired bits,
   # concatenate them into one long line, then format as a table.  The data
   # comes out in this order for each paragraph:
   # $2  Size         2048 MB
   # $3  Form Factor  <OUT OF SPEC>
   # $4  Locator      DIMM1
   # $5  Type         <OUT OF SPEC>
   # $6  Type Detail  Synchronous
   # $7  Speed        667 MHz (1.5 ns)
   sed    -e '/./{H;$!d;}' \
          -e 'x;/Memory Device\n/!d;' \
          -e 's/: /:/g' \
          -e 's/</{/g' \
          -e 's/>/}/g' \
          -e 's/[ \t]*\n/\n/g' \
       /tmp/aspersa \
       | awk -F: '/Size|Type|Form.Factor|Type.Detail|[^ ]Locator/{printf("|%s", $2)}/Speed/{print "|" $2}' \
       | sed -e 's/No Module Installed/{EMPTY}/' \
       | sort \
       | awk -F'|' '{printf("  %-9s %-8s %-17s %-13s %-13s %-8s\n", $4, $2, $7, $3, $5, $6);}'
}

# ##############################################################################
# Parse the output of 'netstat -antp'
# ##############################################################################
parse_ip_s_link () {
   echo "  interface  rx_bytes rx_packets  rx_errors   tx_bytes tx_packets  tx_errors"
   echo "  ========= ========= ========== ========== ========== ========== =========="

   awk "/^[1-9][0-9]*:/ {
      save[\"iface\"] = substr(\$2, 0, index(\$2, \":\") - 1);
      new = 1;
   }
   \$0 !~ /[^0-9 ]/ {
      if ( new == 1 ) {
         new = 0;
         fuzzy_var = \$1; ${fuzzy_formula} save[\"bytes\"] = fuzzy_var;
         fuzzy_var = \$2; ${fuzzy_formula} save[\"packs\"] = fuzzy_var;
         fuzzy_var = \$3; ${fuzzy_formula} save[\"errs\"]  = fuzzy_var;
      }
      else {
         fuzzy_var = \$1; ${fuzzy_formula} tx_bytes   = fuzzy_var;
         fuzzy_var = \$2; ${fuzzy_formula} tx_packets = fuzzy_var;
         fuzzy_var = \$3; ${fuzzy_formula} tx_errors  = fuzzy_var;
         printf \"  %-8s %10d %10d %10d %10d %10d %10d\\n\", save[\"iface\"], save[\"bytes\"], save[\"packs\"], save[\"errs\"], tx_bytes, tx_packets, tx_errors;
      }
   }" $@
}

# ##############################################################################
# Parse the output of 'netstat -antp' which should be in /tmp/aspersa.
# ##############################################################################
parse_netstat () {
   echo "  Connections from remote IP addresses"
   awk '$1 ~ /^tcp/ && $5 ~ /^[1-9]/ {
      print substr($5, 0, index($5, ":") - 1);
   }' /tmp/aspersa | sort | uniq -c \
      | awk "{
         fuzzy_var=\$1;
         ${fuzzy_formula}
         printf \"    %-15s %5d\\n\", \$2, fuzzy_var;
         }" \
      | sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4
   echo "  Connections to local IP addresses"
   awk '$1 ~ /^tcp/ && $5 ~ /^[1-9]/ {
      print substr($4, 0, index($4, ":") - 1);
   }' /tmp/aspersa | sort | uniq -c \
      | awk "{
         fuzzy_var=\$1;
         ${fuzzy_formula}
         printf \"    %-15s %5d\\n\", \$2, fuzzy_var;
         }" \
      | sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4
   echo "  Connections to top 10 local ports"
   awk '$1 ~ /^tcp/ && $5 ~ /^[1-9]/ {
      print substr($4, index($4, ":") + 1);
   }' /tmp/aspersa | sort | uniq -c | sort -rn | head -n10 \
      | awk "{
         fuzzy_var=\$1;
         ${fuzzy_formula}
         printf \"    %-15s %5d\\n\", \$2, fuzzy_var;
         }" | sort
   echo "  States of connections"
   awk '$1 ~ /^tcp/ {
      print $6;
   }' /tmp/aspersa | sort | uniq -c | sort -rn \
      | awk "{
         fuzzy_var=\$1;
         ${fuzzy_formula}
         printf \"    %-15s %5d\\n\", \$2, fuzzy_var;
         }" | sort
}

# ##############################################################################
# Parse the joined output of 'mount' and 'df -hP'.  $1 = file; $2 = ostype.
# ##############################################################################
parse_filesystems () {
   # Filesystem names and mountpoints can be very long.  We try to align things
   # as nicely as possible by making columns only as wide as needed.  This
   # requires two passes through the file.  The first pass finds the max size of
   # these columns and prints out a printf spec, and the second prints out the
   # file nicely aligned.
   cat > /tmp/aspersa.awk <<-EOF
      BEGIN {
         device     = 10;
         fstype     = 4;
         options    = 4;
      }
      /./ {
         f_device     = \$1;
         f_fstype     = \$10;
         f_options    = substr(\$11, 2, length(\$11) - 2);
         if ( "$2" == "FreeBSD" ) {
            f_fstype  = substr(\$9, 2, length(\$9) - 2);
            f_options = substr(\$0, index(\$0, ",") + 2);
            f_options = substr(f_options, 1, length(f_options) - 1);
         }
         if ( length(f_device) > device ) {
            device=length(f_device);
         }
         if ( length(f_fstype) > fstype ) {
            fstype=length(f_fstype);
         }
         if ( length(f_options) > options ) {
            options=length(f_options);
         }
      }
      END{
         print "%-" device "s %5s %4s %-" fstype "s %-" options "s %s";
      }
	EOF
   spec="$( awk -f /tmp/aspersa.awk "$1" )";
   #awk -f /tmp/aspersa.awk "$1"
   #return;

   cat > /tmp/aspersa.awk <<-EOF
      BEGIN {
         spec="  ${spec}\\n";
         printf spec, "Filesystem", "Size", "Used", "Type", "Opts", "Mountpoint";
      }
      {
         f_fstype     = \$10;
         f_options    = substr(\$11, 2, length(\$11) - 2);
         if ( "$2" == "FreeBSD" ) {
            f_fstype  = substr(\$9, 2, length(\$9) - 2);
            f_options = substr(\$0, index(\$0, ",") + 2);
            f_options = substr(f_options, 1, length(f_options) - 1);
         }
         printf spec, \$1, \$2, \$5, f_fstype, f_options, \$6;
      }
	EOF
   awk -f /tmp/aspersa.awk "$1"
}

# ##############################################################################
# Parse the output of fdisk -l, which should be in /tmp/aspersa; there might be
# multiple fdisk -l outputs in the file.
# ##############################################################################
parse_fdisk () {
   awk '
      BEGIN {
         format="%-12s %4s %10s %10s %18s\n";
         printf(format, "Device", "Type", "Start", "End", "Size");
         printf(format, "============", "====", "==========", "==========", "==================");
      }
      /Disk.*bytes/ {
         disk = substr($2, 1, length($2) - 1);
         size = $5;
         printf(format, disk, "Disk", "", "", size);
      }
      /Units/ {
         units = $9;
      }
      /^\/dev/ {
         if ( $2 == "*" ) {
            start = $3;
            end   = $4;
         }
         else {
            start = $2;
            end   = $3;
         }
         printf(format, $1, "Part", start, end, sprintf("%.0f", (end - start) * units));
      }
   ' /tmp/aspersa
}

# ##############################################################################
# Parse the output of dmesg, which should be in /tmp/aspersa, and detect
# virtualization.
# ##############################################################################
parse_virtualization_dmesg () {
   if grep -qi -e vmware -e vmxnet -e 'paravirtualized kernel on vmi' /tmp/aspersa; then
      echo "VMWare";
   elif grep -qi -e 'paravirtualized kernel on xen' -e 'Xen virtual console' /tmp/aspersa; then
      echo "Xen";
   elif grep -qi qemu /tmp/aspersa; then
      echo "QEmu";
   elif grep -qi 'paravirtualized kernel on KVM' /tmp/aspersa; then
      echo "KVM";
   elif grep -q VBOX /tmp/aspersa; then
      echo "VirtualBox";
   elif grep -qi 'hd.: Virtual .., ATA.*drive' /tmp/aspersa; then
      echo "Microsoft VirtualPC";
   fi
}

# ##############################################################################
# Try to figure out if a system is a guest by looking at prtdiag, smbios, etc.
# ##############################################################################
parse_virtualization_generic() {
   if grep -i -e virtualbox "$1" >/dev/null; then
      echo VirtualBox
   elif grep -i -e vmware "$1" >/dev/null; then
      echo VMWare
   fi
}

# ##############################################################################
# Parse the output of lspci, which should be in /tmp/aspersa, and detect
# Ethernet cards.
# ##############################################################################
parse_ethernet_controller_lspci () {
   grep -i ethernet /tmp/aspersa | cut -d: -f3 | while read line; do
      name_val Controller "${line}"
   done
}

# ##############################################################################
# Parse the output of lspci, which should be in /tmp/aspersa, and detect RAID
# controllers.
# ##############################################################################
parse_raid_controller_lspci () {
   if grep -q "RAID bus controller: LSI Logic / Symbios Logic MegaRAID SAS" /tmp/aspersa; then
      echo 'LSI Logic MegaRAID SAS'
   elif grep -q "Fusion-MPT SAS" /tmp/aspersa; then
      echo 'Fusion-MPT SAS'
   elif grep -q "RAID bus controller: LSI Logic / Symbios Logic Unknown" /tmp/aspersa; then
      echo 'LSI Logic Unknown'
   elif grep -q "RAID bus controller: Adaptec AAC-RAID" /tmp/aspersa; then
      echo 'AACRAID'
   elif grep -q "3ware [0-9]* Storage Controller" /tmp/aspersa; then
      echo '3Ware'
   elif grep -q "Hewlett-Packard Company Smart Array" /tmp/aspersa; then
      echo 'HP Smart Array'
   elif grep -q " RAID bus controller: " /tmp/aspersa; then
      awk -F: '/RAID bus controller\:/ {print $3" "$5" "$6}' /tmp/aspersa
   fi
}

# ##############################################################################
# Parse the output of dmesg, which should be in /tmp/aspersa, and detect RAID
# controllers.
# ##############################################################################
parse_raid_controller_dmesg () {
   pat='scsi[0-9].*: .*'
   if grep -qi "${pat}megaraid" /tmp/aspersa; then
      echo 'LSI Logic MegaRAID SAS'
   elif grep -q "Fusion MPT SAS" /tmp/aspersa; then
      echo 'Fusion-MPT SAS'
   elif grep -q "${pat}aacraid" /tmp/aspersa; then
      echo 'AACRAID'
   elif grep -q "${pat}3ware [0-9]* Storage Controller" /tmp/aspersa; then
      echo '3Ware'
   fi
}

# ##############################################################################
# Parse the output of "hpacucli ctrl all show config", which should be stored in
# /tmp/aspersa
# ##############################################################################
parse_hpacucli () {
   grep 'logicaldrive\|physicaldrive' /tmp/aspersa
}

# ##############################################################################
# Parse the output of arcconf, which should be stored in /tmp/aspersa
# ##############################################################################
parse_arcconf () {
   model=$(awk -F: '/Controller Model/{print $2}' /tmp/aspersa)
   chan="$(awk -F: '/Channel description/{print $2}' /tmp/aspersa)"
   cache="$(awk -F: '/Installed memory/{print $2}' /tmp/aspersa)"
   status="$(awk -F: '/Controller Status/{print $2}' /tmp/aspersa)"
   name_val Specs "${model/ /},${chan},${cache} cache,${status}"

   battery=$(grep -A5 'Controller Battery Info' /tmp/aspersa \
      | awk '/Capacity remaining/ {c=$4}
             /Status/             {s=$3}
             /Time remaining/     {t=sprintf("%dd%dh%dm", $7, $9, $11)}
             END                  {printf("%d%%, %s remaining, %s", c, t, s)}')
   name_val Battery "${battery}"

   # ###########################################################################
   # Logical devices
   # ###########################################################################
   echo
   echo "  LogicalDev Size      RAID Disks Stripe Status  Cache"
   echo "  ========== ========= ==== ===== ====== ======= ======="
   for dev in $(awk '/Logical device number/{print $4}' /tmp/aspersa); do
      sed -n -e "/^Logical device .* ${dev}$/,/^$\|^Logical device number/p" \
         /tmp/aspersa \
      | awk '
         /Logical device name/               {d=$5}
         /Size/                              {z=$3 " " $4}
         /RAID level/                        {r=$4}
         /Group [0-9]/                       {g++}
         /Stripe-unit size/                  {p=$4 " " $5}
         /Status of logical/                 {s=$6}
         /Write-cache mode.*Ena.*write-back/ {c="On (WB)"}
         /Write-cache mode.*Ena.*write-thro/ {c="On (WT)"}
         /Write-cache mode.*Disabled/        {c="Off"}
         END {
            printf("  %-10s %-9s %4d %5d %-6s %-7s %-7s\n",
               d, z, r, g, p, s, c);
         }'
   done

   # ###########################################################################
   # Physical devices
   # ###########################################################################
   echo
   echo "  PhysiclDev State   Speed         Vendor  Model        Size        Cache"
   echo "  ========== ======= ============= ======= ============ =========== ======="

   # Find the paragraph with physical devices, tabularize with assoc arrays.
   tempresult=""
   sed -n -e '/Physical Device information/,/^$/p' /tmp/aspersa \
      | awk -F: '
         /Device #[0-9]/ {
            device=substr($0, index($0, "#"));
            devicenames[device]=device;
         }
         /Device is a/ {
            devices[device ",isa"] = substr($0, index($0, "is a") + 5);
         }
         /State/ {
            devices[device ",state"] = substr($2, 2);
         }
         /Transfer Speed/ {
            devices[device ",speed"] = substr($2, 2);
         }
         /Vendor/ {
            devices[device ",vendor"] = substr($2, 2);
         }
         /Model/ {
            devices[device ",model"] = substr($2, 2);
         }
         /Size/ {
            devices[device ",size"] = substr($2, 2);
         }
         /Write Cache/ {
            if ( $2 ~ /Enabled .write-back./ )
               devices[device ",cache"] = "On (WB)";
            else
               if ( $2 ~ /Enabled .write-th/ )
                  devices[device ",cache"] = "On (WT)";
               else
                  devices[device ",cache"] = "Off";
         }
         END {
            for ( device in devicenames ) {
               if ( devices[device ",isa"] ~ /Hard drive/ ) {
                  printf("  %-10s %-7s %-13s %-7s %-12s %-11s %-7s\n",
                     devices[device ",isa"],
                     devices[device ",state"],
                     devices[device ",speed"],
                     devices[device ",vendor"],
                     devices[device ",model"],
                     devices[device ",size"],
                     devices[device ",cache"]);
               }
            }
         }'

}

# ##############################################################################
# Parse the output of "lsiutil -i -s" from /tmp/aspersa
# ##############################################################################
parse_fusionmpt_lsiutil () {
   echo
   awk '/LSI.*Firmware/ { print " ", $0 }' /tmp/aspersa
   grep . /tmp/aspersa | sed -n -e '/B___T___L/,$ {s/^/  /; p}'
}

# ##############################################################################
# Parse the output of MegaCli64 -AdpAllInfo -aALL from /tmp/aspersa.
# ##############################################################################
parse_lsi_megaraid_adapter_info () {
   name=$(awk -F: '/Product Name/{print substr($2, 2)}' /tmp/aspersa);
   int=$(awk '/Host Interface/{print $4}' /tmp/aspersa);
   prt=$(awk '/Number of Backend Port/{print $5}' /tmp/aspersa);
   bbu=$(awk '/^BBU             :/{print $3}' /tmp/aspersa);
   mem=$(awk '/Memory Size/{print $4}' /tmp/aspersa);
   vdr=$(awk '/Virtual Drives/{print $4}' /tmp/aspersa);
   dvd=$(awk '/Degraded/{print $3}' /tmp/aspersa);
   phy=$(awk '/^  Disks/{print $3}' /tmp/aspersa);
   crd=$(awk '/Critical Disks/{print $4}' /tmp/aspersa);
   fad=$(awk '/Failed Disks/{print $4}' /tmp/aspersa);
   name_val Model "${name}, ${int} interface, ${prt} ports"
   name_val Cache "${mem} Memory, BBU ${bbu}"
}

# ##############################################################################
# Parse the output (saved in /tmp/aspersa) of
# /opt/MegaRAID/MegaCli/MegaCli64 -AdpBbuCmd -GetBbuStatus -aALL
# ##############################################################################
parse_lsi_megaraid_bbu_status () {
   charge=$(awk '/Relative State/{print $5}' /tmp/aspersa);
   temp=$(awk '/^Temperature/{print $2}' /tmp/aspersa);
   soh=$(awk '/isSOHGood:/{print $2}' /tmp/aspersa);
   name_val BBU "${charge}% Charged, Temperature ${temp}C, isSOHGood=${soh}"
}

# ##############################################################################
# Parse physical devices from the output (saved in /tmp/aspersa) of
# /opt/MegaRAID/MegaCli/MegaCli64 -LdPdInfo -aALL
# OR, it will also work with the output of
# /opt/MegaRAID/MegaCli/MegaCli64 -PDList -aALL
# ##############################################################################
parse_lsi_megaraid_devices () {
   echo
   echo "  PhysiclDev Type State   Errors Vendor  Model        Size"
   echo "  ========== ==== ======= ====== ======= ============ ==========="
   for dev in $(awk '/Device Id/{print $3}' /tmp/aspersa); do
      sed -e '/./{H;$!d;}' -e "x;/Device Id: ${dev}/!d;" /tmp/aspersa \
      | awk '
         /Media Type/                        {d=substr($0, index($0, ":") + 2)}
         /PD Type/                           {t=$3}
         /Firmware state/                    {s=$3}
         /Media Error Count/                 {me=$4}
         /Other Error Count/                 {oe=$4}
         /Predictive Failure Count/          {pe=$4}
         /Inquiry Data/                      {v=$3; m=$4;}
         /Raw Size/                          {z=$3}
         END {
            printf("  %-10s %-4s %-7s %6s %-7s %-12s %-7s\n",
               substr(d, 0, 10), t, s, me "/" oe "/" pe, v, m, z);
         }'
   done
}

# ##############################################################################
# Parse virtual devices from the output (saved in /tmp/aspersa) of
# /opt/MegaRAID/MegaCli/MegaCli64 -LdPdInfo -aALL
# OR, it will also work with the output of
# /opt/MegaRAID/MegaCli/MegaCli64 -LDInfo -Lall -aAll
# ##############################################################################
parse_lsi_megaraid_virtual_devices () {
   # Somewhere on the Internet, I found the following guide to understanding the
   # RAID level, but I don't know the source anymore.
   #    Primary-0, Secondary-0, RAID Level Qualifier-0 = 0
   #    Primary-1, Secondary-0, RAID Level Qualifier-0 = 1
   #    Primary-5, Secondary-0, RAID Level Qualifier-3 = 5
   #    Primary-1, Secondary-3, RAID Level Qualifier-0 = 10
   # I am not sure if this is always correct or not (it seems correct).  The
   # terminology MegaRAID uses is not clear to me, and isn't documented that I
   # am aware of.  Anyone who can clarify the above, please contact me.
   echo
   echo "  VirtualDev Size      RAID Level Disks SpnDpth Stripe Status  Cache"
   echo "  ========== ========= ========== ===== ======= ====== ======= ========="
   awk '
      /^Virtual Disk:/ {
         device              = $3;
         devicenames[device] = device;
      }
      /Number Of Drives/ {
         devices[device ",numdisks"] = substr($0, index($0, ":") + 1);
      }
      /^Name:/ {
         devices[device ",name"] = $2 > "" ? $2 : "(no name)";
      }
      /RAID Level/ {
         devices[device ",primary"]   = substr($3, index($3, "-") + 1, 1);
         devices[device ",secondary"] = substr($4, index($4, "-") + 1, 1);
         devices[device ",qualifier"] = substr($NF, index($NF, "-") + 1, 1);
      }
      /Span Depth/ {
         devices[device ",spandepth"] = substr($2, index($2, ":") + 1);
      }
      /Number of Spans/ {
         devices[device ",numspans"] = $4;
      }
      /^Size:/ {
         devices[device ",size"] = substr($0, index($0, ":") + 1);
      }
      /^State:/ {
         devices[device ",state"] = $2;
      }
      /^Stripe Size:/ {
         devices[device ",stripe"] = $3;
      }
      /^Current Cache Policy/ {
         devices[device ",wpolicy"] = $4 ~ /WriteBack/ ? "WB" : "WT";
         devices[device ",rpolicy"] = $5 ~ /ReadAheadNone/ ? "no RA" : "RA";
      }
      END {
         for ( device in devicenames ) {
            raid = 0;
            if ( devices[device ",primary"] == 1 ) {
               raid = 1;
               if ( devices[device ",secondary"] == 3 ) {
                  raid = 10;
               }
            }
            else {
               if ( devices[device ",primary"] == 5 ) {
                  raid = 5;
               }
            }
            printf("  %-10s %-9s %-10s %5d %7s %6s %-7s %s\n",
               device devices[device ",name"],
               devices[device ",size"],
               raid " (" devices[device ",primary"] "-" devices[device ",secondary"] "-" devices[device ",qualifier"] ")",
               devices[device ",numdisks"],
               devices[device ",spandepth"] "-" devices[device ",numspans"],
               devices[device ",stripe"], devices[device ",state"],
               devices[device ",wpolicy"] ", " devices[device ",rpolicy"]);
         }
      }' /tmp/aspersa
}

# ##############################################################################
# Simplifies vmstat and aligns it nicely.  We don't need the memory stats, the
# system activity is enough.
# ##############################################################################
format_vmstat () {
   cat > /tmp/aspersa.awk <<-EOF
      BEGIN {
         format = "  %2s %2s  %4s %4s %5s %5s %6s %6s %3s %3s %3s %3s %3s\n";
      }
      /procs/ {
         print  "  procs  ---swap-- -----io---- ---system---- --------cpu--------";
      }
      /bo/ {
         printf format, "r", "b", "si", "so", "bi", "bo", "ir", "cs", "us", "sy", "il", "wa", "st";
      }
      \$0 !~ /r/ {
            fuzzy_var = \$1;   ${fuzzy_formula}  r   = fuzzy_var;
            fuzzy_var = \$2;   ${fuzzy_formula}  b   = fuzzy_var;
            fuzzy_var = \$7;   ${fuzzy_formula}  si  = fuzzy_var;
            fuzzy_var = \$8;   ${fuzzy_formula}  so  = fuzzy_var;
            fuzzy_var = \$9;   ${fuzzy_formula}  bi  = fuzzy_var;
            fuzzy_var = \$10;  ${fuzzy_formula}  bo  = fuzzy_var;
            fuzzy_var = \$11;  ${fuzzy_formula}  ir  = fuzzy_var;
            fuzzy_var = \$12;  ${fuzzy_formula}  cs  = fuzzy_var;
            fuzzy_var = \$13;                    us  = fuzzy_var;
            fuzzy_var = \$14;                    sy  = fuzzy_var;
            fuzzy_var = \$15;                    il  = fuzzy_var;
            fuzzy_var = \$16;                    wa  = fuzzy_var;
            fuzzy_var = \$17;                    st  = fuzzy_var;
            printf format, r, b, si, so, bi, bo, ir, cs, us, sy, il, wa, st;
         }
	EOF
      awk -f /tmp/aspersa.awk /tmp/aspersa
   }

# ##############################################################################
# The main() function is called at the end of the script.  This makes it
# testable.  Major bits of parsing are separated into functions for testability.
# As a general rule, we cannot 'cp' files from /proc, because they might be
# empty afterwards.  (I've seen 'cp /proc/cpuinfo' create an empty file.)  But
# 'cat' works okay.
# ##############################################################################
main () {

   # Begin by setting the $PATH to include some common locations that are not
   # always in the $PATH, including the "sbin" locations, and some common
   # locations for proprietary management software, such as RAID controllers.
   export PATH="${PATH}:/usr/local/bin:/usr/bin:/bin:/usr/libexec"
   export PATH="${PATH}:/usr/local/sbin:/usr/sbin:/sbin"
   export PATH="${PATH}:/usr/StorMan/:/opt/MegaRAID/MegaCli/";

   # Set up temporary files.
   temp_files "rm"
   temp_files "touch"
   section Aspersa_System_Summary_Report

   # ########################################################################
   # Grab a bunch of stuff and put it into temp files for later.
   # ########################################################################
   sysctl -a > /tmp/aspersa.sysctl 2>/dev/null

   # ########################################################################
   # General date, time, load, etc
   # ########################################################################
   platform="$(uname -s)"
   name_val "Date" "`date -u +'%F %T UTC'` (local TZ: `date +'%Z %z'`)"
   name_val "Hostname" "$(uname -n)"
   name_val "Uptime" "$(uptime | awk '{print substr($0, index($0, "up") + 3)}')"
   if which dmidecode > /dev/null 2>&1; then
      vendor="$(dmidecode -s system-manufacturer 2>/dev/null | sed 's/ *$//g')"
      if [ "${vendor}" ]; then
         product="$(dmidecode -s system-product-name 2>/dev/null | sed 's/ *$//g')"
         version="$(dmidecode -s system-version 2>/dev/null | sed 's/ *$//g')"
         chassis="$(dmidecode -s chassis-type 2>/dev/null | sed 's/ *$//g')"
         system="${vendor}; ${product}; v${version} (${chassis})"
         name_val "System" "${system}";
         servicetag="$(dmidecode -s system-serial-number 2>/dev/null | sed 's/ *$//g')"
         name_val "Service Tag" "${servicetag:-Not found}";
      fi
   fi
   name_val "Platform" "${platform}"
   if [ "${platform}" = "SunOS" ]; then
      if which zonename >/dev/null 2>&1 ; then
         name_val "Zonename" "$(zonename)"
      fi
   fi

   # Try to find all sorts of different files that say what the release is.
   if [ "${platform}" = "Linux" ]; then
      kernel="$(uname -r)"
      if [ -e /etc/fedora-release ]; then
         release=$(cat /etc/fedora-release);
      elif [ -e /etc/redhat-release ]; then
         release=$(cat /etc/redhat-release);
      elif [ -e /etc/system-release ]; then
         release=$(cat /etc/system-release);
      elif which lsb_release >/dev/null 2>&1; then
         release="$(lsb_release -ds) ($(lsb_release -cs))"
      elif [ -e /etc/lsb-release ]; then
         release=$(grep DISTRIB_DESCRIPTION /etc/lsb-release |awk -F'=' '{print $2}' |sed 's#"##g');
      elif [ -e /etc/debian_version ]; then
         release="Debian-based version $(cat /etc/debian_version)";
         if [ -e /etc/apt/sources.list ]; then
             code=`cat /etc/apt/sources.list |awk  '/^deb/ {print $3}' |awk -F/ '{print $1}'| awk 'BEGIN {FS="|"}{print $1}' | sort | uniq -c | sort -rn |head -n1 |awk '{print $2}'`
             release="${release} (${code})"
      fi
      elif ls /etc/*release >/dev/null 2>&1; then
         if grep -q DISTRIB_DESCRIPTION /etc/*release; then
            release=$(grep DISTRIB_DESCRIPTION /etc/*release | head -n1);
         else
            release=$(cat /etc/*release | head -n1);
         fi
      fi
   elif [ "${platform}" = "FreeBSD" ]; then
      release="$(uname -r)"
      kernel="$(sysctl -n kern.osrevision)"
   elif [ "${platform}" = "SunOS" ]; then
      release="$(head -n1 /etc/release)"
      if [ -z "${release}" ]; then
         release="$(uname -r)"
      fi
      kernel="$(uname -v)"
   fi
   name_val Release "${release}"
   name_val Kernel "${kernel}"

   CPU_ARCH='32-bit'
   OS_ARCH='32-bit'
   if [ "${platform}" = "Linux" ]; then
      if grep -q ' lm ' /proc/cpuinfo; then
         CPU_ARCH='64-bit'
      fi
   elif [ "${platform}" = "FreeBSD" ]; then
      if sysctl hw.machine_arch | grep -v 'i[36]86' >/dev/null; then
         CPU_ARCH='64-bit'
      fi
   elif [ "${platform}" = "SunOS" ]; then
      if isainfo -b | grep 64 >/dev/null ; then
         CPU_ARCH="64-bit"
      fi
   fi
   if file /bin/sh | grep '64-bit' >/dev/null; then
      OS_ARCH='64-bit'
   fi
   name_val "Architecture" "CPU = $CPU_ARCH, OS = $OS_ARCH"

   # Threading library
   if [ "${platform}" = "Linux" ]; then
      name_val Threading "$(getconf GNU_LIBPTHREAD_VERSION)"
   fi
   if [ -x /lib/libc.so.6 ]; then
      name_val "Compiler" "$(/lib/libc.so.6 | grep 'Compiled by' | cut -c13-)"
   fi

   if [ "${platform}" = "Linux" ]; then
      if getenforce >/dev/null 2>&1; then
         getenforce="$(getenforce 2>&1)";
      fi
      name_val "SELinux" "${getenforce:-No SELinux detected}";
   fi

   # We look in dmesg for virtualization information first, because it's often
   # available to non-root users and usually has telltale signs.  It's most
   # reliable to look at /var/log/dmesg if possible.  There are a number of
   # other ways to find out if a system is virtualized.
   cat /var/log/dmesg > /tmp/aspersa 2>/dev/null
   if [ ! -s /tmp/aspersa ]; then
      dmesg > /tmp/aspersa 2>/dev/null
   fi
   if [ -s /tmp/aspersa ]; then
      virt="$(parse_virtualization_dmesg)"
   fi
   if [ -z "${virt}" ]; then
      if which lspci >/dev/null 2>&1; then
         lspci > /tmp/aspersa 2>/dev/null
         if grep -qi virtualbox /tmp/aspersa; then
            virt=VirtualBox
         elif grep -qi vmware /tmp/aspersa; then
            virt=VMWare
         elif [ -e /proc/user_beancounters ]; then
            virt="OpenVZ/Virtuozzo"
         fi
      fi
   elif [ "${platform}" = "FreeBSD" ]; then
      if ps -o stat | grep J ; then
         virt="FreeBSD Jail"
      fi
   elif [ "${platform}" = "SunOS" ]; then
      if which prtdiag >/dev/null 2>&1 && prtdiag > /tmp/aspersa.prtdiag 2>/dev/null; then
         virt="$(parse_virtualization_generic /tmp/aspersa.prtdiag)"
      elif which smbios >/dev/null 2>&1 && smbios > /tmp/aspersa.smbios 2>/dev/null; then
         virt="$(parse_virtualization_generic /tmp/aspersa.smbios)"
      fi
   fi
   name_val Virtualized "${virt:-No virtualization detected}"

   # ########################################################################
   # Processor/CPU, Memory, Swappiness, dmidecode
   # ########################################################################
   section Processor
   if [ -f /proc/cpuinfo ]; then
      cat /proc/cpuinfo > /tmp/aspersa 2>/dev/null
      parse_proc_cpuinfo
   elif [ "${platform}" = "FreeBSD" ]; then
      parse_sysctl_cpu_freebsd /tmp/aspersa.sysctl
   elif [ "${platform}" = "SunOS" ]; then
      psrinfo -v > /tmp/aspersa
      parse_psrinfo_cpus /tmp/aspersa
      # TODO: prtconf -v actually prints the CPU model name etc.
   fi

   section Memory
   if [ "${platform}" = "Linux" ]; then
      free -b > /tmp/aspersa
      cat /proc/meminfo >> /tmp/aspersa
      parse_free_minus_b /tmp/aspersa
   elif [ "${platform}" = "FreeBSD" ]; then
      parse_memory_sysctl_freebsd /tmp/aspersa.sysctl
   elif [ "${platform}" = "SunOS" ]; then
      name_val Memory "$(prtconf | awk -F: '/Memory/{print $2}')"
   fi

   rss=$(ps -eo rss 2>/dev/null | awk '/[0-9]/{total += $1 * 1024} END {print total}')
   name_val UsedRSS "$(shorten ${rss} 1)"

   if [ "${platform}" = "Linux" ]; then
      name_val Swappiness "$(sysctl vm.swappiness 2>&1)"
      name_val DirtyPolicy "$(sysctl vm.dirty_ratio 2>&1), $(sysctl vm.dirty_background_ratio 2>&1)"
      if sysctl vm.dirty_bytes > /dev/null 2>&1; then
         name_val DirtyStatus "$(sysctl vm.dirty_bytes 2>&1), $(sysctl vm.dirty_background_bytes 2>&1)"
      fi
   fi

   if which dmidecode >/dev/null 2>&1 && dmidecode > /tmp/aspersa 2>/dev/null; then
      parse_dmidecode_mem_devices
   fi

   # ########################################################################
   # Disks, RAID, Filesystems
   # ########################################################################
   # TODO: Add info about software RAID

   if echo "${ASPERSA_SKIP}" | grep -v MOUNT >/dev/null; then
      if [ "${platform}" != "SunOS" ]; then
         section "Mounted_Filesystems"
         cmd="df -h"
         if [ "${platform}" = "Linux" ]; then
            cmd="df -h -P"
         fi
         $cmd | sort > /tmp/aspersa2
         mount | sort | join /tmp/aspersa2 - > /tmp/aspersa
         parse_filesystems /tmp/aspersa "${platform}"
      fi
   fi

   if [ "${platform}" = "Linux" ]; then
      section "Disk_Schedulers_And_Queue_Size"
      echo "" > /tmp/aspersa
      for disk in $(ls /sys/block/ | grep -v -e ram -e loop -e 'fd[0-9]'); do
         if [ -e "/sys/block/${disk}/queue/scheduler" ]; then
            name_val "${disk}" "$(cat /sys/block/${disk}/queue/scheduler | grep -o '\[.*\]') $(cat /sys/block/${disk}/queue/nr_requests)"
            fdisk -l "/dev/${disk}" >> /tmp/aspersa 2>/dev/null
         fi
      done

      # Relies on /tmp/aspersa having data from the Disk Schedulers loop.
      section "Disk_Partioning"
      parse_fdisk

      section "Kernel_Inode_State"
      for file in dentry-state file-nr inode-nr; do
         name_val "${file}" "$(cat /proc/sys/fs/${file} 2>&1)"
      done

      section "LVM_Volumes"

      if which lvs >/dev/null 2>&1 && test -x "$(which lvs)"; then
         lvs 2>&1
      else
         echo "Cannot execute 'lvs'";
      fi
   fi

   section "RAID_Controller"

   # ########################################################################
   # We look in lspci first because it's more reliable, then dmesg, because it's
   # often available to non-root users.  It's most reliable to look at
   # /var/log/dmesg if possible.
   # ########################################################################
   if which lspci >/dev/null 2>&1 && lspci > /tmp/aspersa 2>/dev/null; then
      controller="$(parse_raid_controller_lspci)"
   fi
   if [ -z "${controller}" ]; then
      cat /var/log/dmesg > /tmp/aspersa 2>/dev/null
      if [ ! -s /tmp/aspersa ]; then
         dmesg > /tmp/aspersa 2>/dev/null
      fi
      controller="$(parse_raid_controller_dmesg)"
   fi

   name_val Controller "${controller:-No RAID controller detected}"

   # ########################################################################
   # Attempt to get, parse, and print RAID controller status from possibly
   # proprietary management software.  Any executables that are normally stored
   # in a weird location, such as /usr/StorMan/arcconf, should have their
   # location added to $PATH at the beginning of main().
   # ########################################################################
   notfound=""
   if [ "${controller}" = "AACRAID" ]; then
      if arcconf getconfig 1 > /tmp/aspersa 2>/dev/null; then
         parse_arcconf
      elif ! which arcconf >/dev/null 2>&1; then
         notfound="e.g. http://www.adaptec.com/en-US/support/raid/scsi_raid/ASR-2120S/"
      fi
   elif [ "${controller}" = "HP Smart Array" ]; then
      if hpacucli ctrl all show config > /tmp/aspersa 2>/dev/null; then
         parse_hpacucli
      elif ! which hpacucli >/dev/null 2>&1; then
         notfound="your package repository or the manufacturer's website"
      fi
   elif [ "${controller}" = "LSI Logic MegaRAID SAS" ]; then
      if MegaCli64 -AdpAllInfo -aALL -NoLog > /tmp/aspersa 2>/dev/null; then
         parse_lsi_megaraid_adapter_info
      elif ! which MegaCli64 >/dev/null 2>&1; then
         notfound="your package repository or the manufacturer's website"
      fi
      if MegaCli64 -AdpBbuCmd -GetBbuStatus -aALL -NoLog > /tmp/aspersa 2>/dev/null; then
         parse_lsi_megaraid_bbu_status
      fi
      if MegaCli64 -LdPdInfo -aALL -NoLog > /tmp/aspersa 2>/dev/null; then
         parse_lsi_megaraid_virtual_devices
         parse_lsi_megaraid_devices
      fi
   fi

   if [ "${notfound}" ]; then
      echo "   RAID controller software not found; try getting it from"
      echo "   ${notfound}"
   fi

   if echo "${ASPERSA_SKIP}" | grep -v NETWORK >/dev/null; then
      # #####################################################################
      # Network stuff
      # #####################################################################
      if [ "${platform}" = "Linux" ]; then
         section Network_Config
         if which lspci > /dev/null 2>&1 && lspci > /tmp/aspersa 2>/dev/null; then
            parse_ethernet_controller_lspci
         fi
         if sysctl net.ipv4.tcp_fin_timeout > /dev/null 2>&1; then
            name_val "FIN Timeout" "$(sysctl net.ipv4.tcp_fin_timeout)"
            name_val "Port Range" "$(sysctl net.ipv4.ip_local_port_range)"
         fi
      fi

      # TODO cat /proc/sys/net/ipv4/ip_conntrack_max ; it might be
      # /proc/sys/net/netfilter/nf_conntrack_max or /proc/sys/net/nf_conntrack_max
      # in new kernels like Fedora 12?

      if which ip >/dev/null 2>&1 && ip -s link > /tmp/aspersa 2>/dev/null; then
         section Interface_Statistics
         parse_ip_s_link /tmp/aspersa
      fi

      if [ "${platform}" = "Linux" ]; then
         section Network_Connections
         if netstat -antp > /tmp/aspersa 2>/dev/null; then
            parse_netstat
         fi
      fi
   fi

   # ########################################################################
   # Processes, load, etc
   # ########################################################################
   if echo "${ASPERSA_SKIP}" | grep -v PROCESS >/dev/null; then
      section Top_Processes
      if which prstat > /dev/null 2>&1; then
         prstat | head
      elif which top > /dev/null 2>&1 ; then
         cmd="top -bn 1"
         if [ "${platform}" = "FreeBSD" ]; then
            cmd="top -b -d 1"
         fi
         $cmd | sed -e 's# *$##g' -e '/./{H;$!d;}' -e 'x;/PID/!d;' | grep . | head
      fi
      if which vmstat > /dev/null 2>&1 ; then
         section "Simplified_and_fuzzy_rounded_vmstat_(wait_please)"
         vmstat 1 5 > /tmp/aspersa
         if [ "${platform}" = "Linux" ]; then
            format_vmstat
         else
            # TODO: simplify/format for other platforms
            cat /tmp/aspersa
         fi
      fi
   fi

   # ########################################################################
   # All done.  Signal the end so it's explicit.
   # ########################################################################
   temp_files "rm"
   temp_files "check"
   section The_End
}

# Execute the program if it was not included from another file.  This makes it
# possible to include without executing, and thus test.
if [ "$(basename "$0")" = "summary" ] || [ "$(basename "$0")" = "bash" -a "$_" = "$0" ]; then
    main $@
fi


这是我开发机器上的信息
# Aspersa System Summary Report ##############################
        Date | 2011-06-12 08:56:30 UTC (local TZ: CST +0800)
    Hostname | ubuntu1104-dev01
      Uptime | 2 days, 6:37, 2 users, load average: 0.00, 0.01, 0.05
      System | Dell Inc.; OptiPlex 990; v01 (Mini Tower)
 Service Tag | XXXXXXX
    Platform | Linux
     Release | Ubuntu 11.04 (natty)
      Kernel | 2.6.38-8-generic
Architecture | CPU = 64-bit, OS = 64-bit
   Threading | NPTL 2.13
     SELinux | No SELinux detected
 Virtualized | No virtualization detected
# Processor ##################################################
  Processors | physical = 1, cores = 4, virtual = 8, hyperthreading = yes
      Speeds | 7x1600.000, 1x2600.000
      Models | 8xIntel(R) Core(TM) i7-2600 CPU @ 3.40GHz
      Caches | 8x8192 KB
# Memory #####################################################
       Total | 15.66G
        Free | 13.08G
        Used | physical = 2.59G, swap = 0.00k, virtual = 2.59G
     Buffers | 175.48M
      Caches | 1.55G
       Dirty | 40 kB
     UsedRSS | 746.0M
  Swappiness | vm.swappiness = 60
 DirtyPolicy | vm.dirty_ratio = 10, vm.dirty_background_ratio = 5
 DirtyStatus | vm.dirty_bytes = 0, vm.dirty_background_bytes = 0
  Locator   Size     Speed             Form Factor   Type          Type Detail
  ========= ======== ================= ============= ============= ===========
  ChannelA-DIMM0 4096 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  ChannelA-DIMM1 4096 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  ChannelB-DIMM0 4096 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  ChannelB-DIMM1 4096 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
# Mounted Filesystems ########################################
  Filesystem  Size Used Type       Opts                             Mountpoint
  /dev/sda1   902G   2% ext4       rw,errors=remount-ro,commit=0    /
  none        7.9G   0% devpts     rw,noexec,nosuid,gid=5,mode=0620 /var/lock
  none        7.9G   0% tmpfs      rw,nosuid,nodev                  /var/lock
  none        7.9G   0% devtmpfs   rw,mode=0755                     /var/lock
  none        7.9G   0% debugfs    rw                               /var/lock
  none        7.9G   0% securityfs rw                               /var/lock
  none        7.9G   0% sysfs      rw,noexec,nosuid,nodev           /var/lock
  none        7.9G   0% tmpfs      rw,noexec,nosuid,nodev           /var/lock
  none        7.9G   0% tmpfs      rw,nosuid,mode=0755              /var/lock
  none        7.9G   1% devpts     rw,noexec,nosuid,gid=5,mode=0620 /dev/shm
  none        7.9G   1% tmpfs      rw,nosuid,nodev                  /dev/shm
  none        7.9G   1% devtmpfs   rw,mode=0755                     /dev/shm
  none        7.9G   1% debugfs    rw                               /dev/shm
  none        7.9G   1% securityfs rw                               /dev/shm
  none        7.9G   1% sysfs      rw,noexec,nosuid,nodev           /dev/shm
  none        7.9G   1% tmpfs      rw,noexec,nosuid,nodev           /dev/shm
  none        7.9G   1% tmpfs      rw,nosuid,mode=0755              /dev/shm
  none        7.9G   1% devpts     rw,noexec,nosuid,gid=5,mode=0620 /dev
  none        7.9G   1% tmpfs      rw,nosuid,nodev                  /dev
  none        7.9G   1% devtmpfs   rw,mode=0755                     /dev
  none        7.9G   1% debugfs    rw                               /dev
  none        7.9G   1% securityfs rw                               /dev
  none        7.9G   1% sysfs      rw,noexec,nosuid,nodev           /dev
  none        7.9G   1% tmpfs      rw,noexec,nosuid,nodev           /dev
  none        7.9G   1% tmpfs      rw,nosuid,mode=0755              /dev
  none        7.9G   1% devpts     rw,noexec,nosuid,gid=5,mode=0620 /var/run
  none        7.9G   1% tmpfs      rw,nosuid,nodev                  /var/run
  none        7.9G   1% devtmpfs   rw,mode=0755                     /var/run
  none        7.9G   1% debugfs    rw                               /var/run
  none        7.9G   1% securityfs rw                               /var/run
  none        7.9G   1% sysfs      rw,noexec,nosuid,nodev           /var/run
  none        7.9G   1% tmpfs      rw,noexec,nosuid,nodev           /var/run
  none        7.9G   1% tmpfs      rw,nosuid,mode=0755              /var/run
# Disk Schedulers And Queue Size #############################
         sda | [cfq] 128
         sr0 | [cfq] 128
# Disk Partioning ############################################
Device       Type      Start        End               Size
============ ==== ========== ========== ==================
/dev/sda     Disk                            1000204886016
/dev/sda1    Part          1     119519       983069015040
/dev/sda2    Part     119519     121602        17133258240
/dev/sda5    Part     119519     121602        17133258240
# Kernel Inode State #########################################
dentry-state | 153236 143621 45 0 0 0
     file-nr | 5664 0 1601386
    inode-nr | 76942 2365
# LVM Volumes ################################################
Cannot execute 'lvs'
# RAID Controller ############################################
  Controller | Intel Corporation 82801 SATA RAID Controller (rev 04)
# Network Config #############################################
  Controller | Intel Corporation 82579LM Gigabit Network Connection (rev 04)
 FIN Timeout | net.ipv4.tcp_fin_timeout = 60
  Port Range | net.ipv4.ip_local_port_range = 32768 61000
# Interface Statistics #######################################
  interface  rx_bytes rx_packets  rx_errors   tx_bytes tx_packets  tx_errors
  ========= ========= ========== ========== ========== ========== ==========
  l        2000000000   12500000          0 2000000000   12500000          0
  eth       100000000     350000          0   12500000      80000          0
  vboxnet           0          0          0          0          0          0
# Network Connections ########################################
  Connections from remote IP addresses
    127.0.0.            2
    192.168.0.23        1
  Connections to local IP addresses
    127.0.0.            2
    192.168.0.24        1
  Connections to top 10 local ports
    22                  1
    4369                1
    45022               1
  States of connections
    ESTABLISHED         3
    LISTEN              8
# Top Processes ##############################################
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    1 root      20   0 24008 2212 1356 S    0  0.0   0:01.78 init
    2 root      20   0     0    0    0 S    0  0.0   0:00.00 kthreadd
    3 root      20   0     0    0    0 S    0  0.0   0:01.98 ksoftirqd/0
    5 root      20   0     0    0    0 S    0  0.0   0:00.25 kworker/u:0
    6 root      RT   0     0    0    0 S    0  0.0   0:00.00 migration/0
    7 root      RT   0     0    0    0 S    0  0.0   0:00.00 migration/1
    8 root      20   0     0    0    0 S    0  0.0   0:03.52 kworker/1:0
    9 root      20   0     0    0    0 S    0  0.0   0:00.77 ksoftirqd/1
   11 root      RT   0     0    0    0 S    0  0.0   0:00.00 migration/2
# Simplified and fuzzy rounded vmstat (wait please) ##########
  procs  ---swap-- -----io---- ---system---- --------cpu--------
   r  b    si   so    bi    bo     ir     cs  us  sy  il  wa  st
   0  0     0    0     1     1     25      1   0   0  99   0    
   0  0     0    0     0     0    250    450   0   0 100   0    
   0  0     0    0     0   125    150    250   0   0  99   1    
   0  0     0    0     0     0    100    150   0   0 100   0    
   0  0     0    0     0     0    100    225   0   0 100   0    
# The End ####################################################
分享到:
评论

相关推荐

    Linux获取服务器硬件配置(CPU、内存、硬盘、主板)信息shell 脚本

    这篇文档将详细解析一个用于获取Linux服务器硬件配置信息的shell脚本,包括CPU、内存、硬盘、PCI Express(PCIe)设备、主板以及系统制造商等关键信息。 首先,让我们逐个分析脚本中的主要命令及其用途: 1. **`...

    java读取服务器硬件信息(windowx+linux+Mac OS)

    对于Linux系统,Java可以通过执行shell命令并解析输出来获取硬件信息。例如,可以使用`/proc`目录下的文件,如`/proc/cpuinfo`和`/proc/meminfo`来获取CPU和内存信息。此外,还可以使用`lshw`命令,它提供了一个详细...

    查询硬件信息shell脚本(系统、cpu、内存、网卡)(仅针对centos7和rh7版本)

    包含,系统、cpu、内存、网卡信息,因硬盘在系统内无法查看是否做过raid,所以没有统计硬盘信息。 [root@localhost ~]#./system 系统信息 系统版本:Centos Linux release 7.9.2009 (Core) 内核版本:Linux 3.10.0-...

    Linux 系统内存性能测试shell脚本

    为了获取更精确的测试结果,可以根据实际硬件配置和应用场景调整脚本中的参数,如`bs`和`count`。例如,如果内存容量较大,可以增加`count`值以适应更大的测试规模。 此外,需要注意的是,由于`drop_caches`操作...

    linux操作系统 shell程序设计

    ### Linux操作系统 Shell程序设计 #### 实验目的 本次实验旨在帮助学习者掌握Linux批处理文件(即shell脚本)的编辑与执行技能,并熟练运用批处理语言进行编程。此外,还将深入了解Linux系统自带的文本编辑器vi的...

    Linux系统基础教程

    教程内容包括了安装Linux系统、配置桌面环境、美化Linux桌面、使用菜单和窗口、配置网络和Shell命令等基础知识,以及文件权限、用户和组管理、硬盘管理、服务器配置等进阶主题。 此外,教程还包括对常用Linux软件如...

    Linux下的硬件信息查看图形化工具

    在Linux操作系统中,虽然命令行工具如`lshw`, `dmidecode`, `cat /proc/cpuinfo`等可以提供详细的硬件信息,但对于不熟悉命令行的用户来说,使用起来可能会感到不便。针对这种情况,一些开发者创建了图形化的硬件...

    linux操作系统基础教程

    ### Linux操作系统基础教程知识点概述 #### 第1章 Linux基础及安装 ##### 1.1 Linux基础知识 - **定义与起源**:Linux是一种免费使用的类UNIX操作系统,它最初由芬兰人Linus Torvalds于1991年开发,并在开源许可证...

    精通 LINUX & UNIX Shell 程序设计.pdf 高清下载

    由于提供的内容中仅包含标题、描述、标签和下载链接的重复信息,并没有具体到Linux和UNIX Shell程序设计的技术细节,因此无法直接从这部分内容中提取出符合要求的知识点。为了满足您的要求,我将基于标题和标签中...

    java获取系统、硬件、设备相关信息

    java 1. 使用wmic相关命令获取windows硬件相关信息。 2. 使用shell相关的dmidecode/fdisk/ifconfig命令获取Linux硬件和系统相关信息

    linux和shell教程

    5. **Linux系统信息查询**:Linux提供了多种命令来获取系统信息,如: - `uname -a`:显示系统内核信息。 - `top`或`htop`:实时查看系统资源使用情况。 - `df`:查看磁盘空间。 - `free`:查看内存使用情况。 ...

    Linux系统操作基础

    本篇文章将详细讲解Linux系统操作的基础知识,包括SSH连接、系统关闭和启动、获取帮助的方法以及文件与目录的操作。 首先,SSH(Secure Shell)是一种网络协议,用于安全地远程登录到Linux系统。它加密所有传输数据...

    LINUX+SHELL脚本攻略.pdf

    根据提供的文件信息,“LINUX+SHELL脚本攻略.pdf”似乎是一份关于Linux系统下的Shell脚本编程指南。这里我们将从几个方面对这份资料可能涵盖的关键知识点进行总结与扩展。 ### Linux简介 Linux是一种免费开放源...

    (完整版)《Linux操作系统及应用项目教程》习题答案.pdf

    1. Linux内核:Linux操作系统的核心部分,负责管理CPU、内存、磁盘等硬件资源,并提供系统服务和管理网络通信等。 2. GNU和Unix:GNU是一个广泛使用的免费软件项目,其目标是创建一套完全自由的操作系统,而Unix是...

    从零基础学习Linux系统完整资料.pdf

    磁盘管理是Linux系统管理中的一个重要方面,包括硬件层面的管理、磁盘分区、格式化、挂载等基础操作,以及高级的磁盘配额和逻辑卷管理(LVM)。Shell编程章节介绍基础和高级的Shell脚本编写,包括正则表达式、字符串...

    Linux基础教程[基于Ubuntu].pdf

    在学习Linux的过程中,需要了解许多基础知识点,包括磁盘的命名规则、文件系统的层次结构、软件包管理工具的使用、网络配置、Shell命令、Linux桌面环境的配置、权限管理、用户和组管理等。磁盘命名规则是Linux系统...

    linux操作系统基础

    Linux操作系统基础涵盖了许多关键概念,从其起源和发展到主要特点,再到不同版本的介绍,都是初学者必须了解的内容。Linux操作系统起源于Ken Thompson的PDP-7计算机上的工作,并通过Minix系统进一步发展,最终在1990...

Global site tag (gtag.js) - Google Analytics