Gathering Linux System Information Using Bash

Following up on my recent post, Simple Bash Server Check Script, I wanted to continue the theme of server monitoring and discuss gathering some basic system information.

In this article I will discuss using Linux tools such as dmidecode to gather information such as server uptime, memory, cpu and networking information.  I will explain some of the commands used, but this post is more about giving you ideas and examples, you will also need to do your own research on the commands to fully understand them.

Linux Distribution Information

There are a number of ways you can get details on which Linux distribution you are running.

Most distributions will have a release file in etc which follow the same naming convention:

  • redhat-release
  • oracle-release
  • centos-release
  • SuSE-release
  • etc.

The following line generally catches all and will suffice.

cat /etc/*-release

which outputs something like this:

PRETTY_NAME="Debian GNU/Linux 7 (wheezy)"
NAME="Debian GNU/Linux"
VERSION_ID="7"
VERSION="7 (wheezy)"
ID=debian
ANSI_COLOR="1;31"
HOME_URL="http://www.debian.org/"
SUPPORT_URL="http://www.debian.org/support/"
BUG_REPORT_URL="http://bugs.debian.org/"

An alternative to the above is the version file in proc.

cat /proc/version

which outputs something like this:

Linux version 2.6.32-5-amd64 (Debian 2.6.32-48squeeze6) (jmm@debian.org) (gcc version 4.3.5 (Debian 4.3.5-4) ) #1 SMP Tue May 13 16:34:35 UTC 2014

You can use awk of sed to pull out the information you need from these commands.

Kernel Information

Uname is the simplest tool to gather this information.  Use different switch’s to gather the information you need.

/bin/uname -a
Linux vimp 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1+deb8u3 (2015-08-04) x86_64 GNU/Linux
/bin/uname -r
3.16.0-4-amd64

System Uptime

Issuing the command uptime will display information such as the current time and how long the system has been up.

For your scripts you might want to make things a little nicer to read so we can pipe this though awk and sed to pull out the information we want.

serveruptime=`uptime|awk '{print $3,$4}'|sed 's/,//'|grep "day"`;
if [[ -z "$serveruptime" ]]; then
serveruptime=`uptime|awk '{print $3}'|sed 's/,//'`;
else
:;
fi;

This is a nice little trick I picked up from a friend and allows you to format the uptime nicely.  The first line pulls the system uptime from the host and assumes it will be more than 24 hours.  The grep actually doesn’t do anything in terms of extracting the data it is there to make the variable empty should the uptime actually be less than one day.  This is useful as we can then check to see if the variable is empty using the -z in the if statement.  If its empty we know the host has only been up for less than 24 hours.

Both uptime statements contain a sed statement that removes the commas from the result.

sed 's/,//'

Physical Server Information

Manufacturer

dmidecode -s system-manufacturer

Model

dmidecode -s system-product-name

Serial Number

dmidecode -s system-serial-number

Network Information

IP Address

ifconfig eth0 |awk '/inet addr:/ {print $2}'|tr -d 'addr:'

Mac Address

ifconfig eth0 |awk '/HWaddr/ {print $5}'

CPU Information

The t4 option in dmidecode can be used to extract CPU information, each CPU will be given a handle which we can use within our scripts to identify each CPU’s information.

dmidecode -t4|awk '/Handle / {print $2}' |sed 's/,//'

This snippet of code will print out a list of CPU handles similar to the following:

0x0400
0x0401

We can then loop though this in our script gathering each CPU’s information.

for cpus in `dmidecode -t4|awk '/Handle / {print $2}'`; do
echo `dmidecode -t4|sed '/Flags/,/Version/d'|egrep -A20 "Handle ${cpus}"|grep -m 1 "Socket Designation"|grep -o '.\{0,0\}:.\{0,18\}'|tr -d '\:| '`;
echo `dmidecode -t4|sed '/Flags/,/Version/d'|egrep -A20 "Handle ${cpus}"|grep -m 1 "Family"|grep -o '.\{0,0\}:.\{0,18\}'|tr -d '\:| '`;
echo `dmidecode -t4|sed '/Flags/,/Version/d'|egrep -A20 "Handle ${cpus}"|grep -m 1 "Manufacturer"|grep -o '.\{0,0\}:.\{0,18\}'|tr -d '\:| '`;
echo `dmidecode -t4|sed '/Flags/,/Version/d'|egrep -A20 "Handle ${cpus}"|grep -m 1 "Current Speed"|grep -o '.\{0,0\}:.\{0,18\}'|tr -d '\:| '`;
echo `dmidecode -t4|sed '/Flags/,/Version/d'|egrep -A20 "Handle ${cpus}"|grep -m 1 "Voltage"|grep -o '.\{0,0\}:.\{0,18\}'|tr -d '\:| '`;
echo `dmidecode -t4|sed '/Flags/,/Version/d'|egrep -A20 "Handle ${cpus}"|grep -m 1 "Core Count"|grep -o '.\{0,0\}:.\{0,18\}'|tr -d '\:| '`;
done

This will output a list similar to the following:

CPU1
Xeon
Intel
2100MHz
1.2V
6

CPU2
Xeon
Intel
2100MHz
1.2V
6

Lets break this down a bit.

sed '/Flags/,/Version/d'

This sed statement removes some unwanted information from the result.  We use two regexp address and delete the information between them.  For more information take a look at the address section of the sed man page.

egrep -A20 "Handle ${cpus}"

The egrep statement looks for eash CPU handle and prints the following 20 lines.  This is how we separate each CPU’s information out.

grep -m 1 "Socket Designation"

Here we simply select the line with the information we want.

grep -o '.\{0,0\}:.\{0,18\}

Now we have the information we want, we start tidying it up into a format we can sue in a script.  Here we remove the initial white space and label.

tr -d '\:| '`;

We then use translate to delete the remaining semi colon and space.

Counting the number of CPU’s installed

dmidecode -t4 |awk '/Populated/ {print $2}'|wc -l

Memory Information

In a similar fashion to CPU information RAM is also assigned a handle which you can use to identify each memory slot and the ram installed in that slot.

Total Number of Slots:

dmidecode -t17 |awk '/Handle / {print $2}'|wc -l

Total populated slots:

dmidecode -t17 |awk '/Size:/'|awk '!/No/'|wc -l

Total unpopulated slots:

dmidecode -t17 |awk '/Size:/'|awk '/No/'|wc -l

The following code snippet works  just like the CPU code above and uses many of the same commands so I will not go into details this time.   This code includes an “if” statement so that we don’t print empty slots, just remove that if you want to print out everything.

for memoryid in `dmidecode -t17|awk '/Handle / {print $2}'|tr -d ','`; do
populated=`dmidecode -t17|grep -A17 "Handle ${memoryid}"|awk '/Size:/ {print $2, $3}'`;
if [[ "$populated" != "No Module" ]]; then
echo `dmidecode -t17|grep -A17 "Handle ${memoryid}"|awk '/Locator:/ {print $2}'|head -1`;
echo `dmidecode -t17|grep -A17 "Handle ${memoryid}"|awk '/Size:/ {print $2, $3}'`;
echo `dmidecode -t17|grep -A17 "Handle ${memoryid}"|awk '/Speed:/ {print $2, $3}'`;
echo `dmidecode -t17|grep -A17 "Handle ${memoryid}"|awk '/Type:/ {print $2, $3}'`;
echo `dmidecode -t17|grep -A17 "Handle ${memoryid}"|awk '/Serial Number:/ {print $3}'`;
echo `dmidecode -t17|grep -A17 "Handle ${memoryid}"|awk '/Part Number:/ {print $3}'`;
echo `/n`;
fi
done

This will print out results like the following:

DIMM_A1
8192 MB
1333 MHz
DDR3
E777893F
36KSF1G72PZ-1G4K1

DIMM_A2
8192 MB
1333 MHz
DDR3
E7778940
36KSF1G72PZ-1G4K1

DIMM_B1
8192 MB
1333 MHz
DDR3
E777888E
36KSF1G72PZ-1G4K1

DIMM_B2
8192 MB
1333 MHz
DDR3
E7778891
36KSF1G72PZ-1G4K1

This should be enough information to get anyone started on creating scripts to capture server information.  I will discuss other hardware such as hard drives at a later date and how we can work all this into some system troubleshooting scripts.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s