IP Monitoring & Diagnostics With Command Line Tools: Part 5 - Using Shell Scripts
Shell scripts enable you to edit your diagnostic and monitoring commands into a script file so they can be repeated without needing to type them manually every time. Shell scripts also offer some unique and powerful features that help to build monitoring systems.
More articles in this series:
Shell scripts encapsulate simple interactive commands so they can be called to action to perform more complex tasks with looping and decision making based on their results. The Input/Output redirection feature alone makes them particularly good at capturing the current state of a server or process and saving it in a cached location where the reporting tools can find it.
What is shell scripting?
The command line shell accepts keystrokes and interprets them as calls to action. A script automates a sequence of commands by taking those same instructions from a file instead of the keyboard.
All of the constructs found in other programming languages, such as loops and conditional execution are available. Shell scripts add unique and interesting features that are not supported in other programming tools.
The first line of your script file
The first line of a UNIX shell script describes the interpreter that executes the script. It starts with a hash and exclamation symbol (#!) followed by the fully qualified path to the interpreter. Here are some examples:
|#!/bin/bash||Call the widely supported Bourne Again (Bash) shell to action.|
|#!/usr/bin/python||Run the script in the default Python interpreter.|
|#!/usr/bin/php||Run the script in the default PHP interpreter.|
|#!/usr/bin/php_56||Run the script in a legacy PHP 5 interpreter.|
|#!/bin/false||Inhibit the script from being run.|
Legacy scripts might need to run in an older version of the interpreter. Choose that here if you need it.
Each process expects one stream of input data and delivers two streams of output text. By default, the command line passes the keyboard characters to the standard input stream and both output streams go to your screen. The streams are called:
The normal output results are transmitted via STDOUT. If something goes wrong, the error messages are transmitted via STDERR. The two streams of text can be processed independently.
The shell can redirect the output streams to a different device, a log file or use them as input to another command. It can also redirect the input from another source instead of the keyboard.
Output redirection examples
Redirect the output of a command with the right facing caret (>) and save it in a file, overwriting any prior content:
ls -la > my_file_list.txt
Double caret symbols (>>) append to the file without overwriting it:
echo "Something went wrong" >> my_log_file.txt
In both cases, a new file will be created automatically if necessary.
This is how to discard the STDERR messages by redirecting them into a null device so they are ignored:
cat my_file.txt 2> /dev/null
Divert the STDOUT of a disk space check to a report file and save the STDERR messages in a log file:
df > output.txt 2>> error.log
Redirect both output streams to the same place. First, redirect STDOUT, then tell STDERR to follow it. This sends the contents of a data file through the sort command with a pipe and then stores the output with any errors that occur.
cat unsorted_data.txt | sort > output.txt 2>&1
Output redirection is incredibly powerful and will be used a great deal in a monitoring system to capture the results from the inspection commands.
Input redirection examples
There are subtle differences in the way the shell executes the commands when you use input redirection. You might only notice these if you monitor process listings while they run or inspect detailed file attributes and date stamps afterwards.
Print a file with one of these commands:
lpr < file_to_print.txt
cat file_to_print.txt | lpr
If you redirect the file using STDIN, or use cat to stream the file to the lpr command, the file name will not appear in the print queue listing. This enhances security and privacy.
Input redirection can read source text embedded within the script. The text is tagged to identify where it ends. We must append the redirected input with double carets (<<) to prevent the text from being executed as commands:
wc -c << EOF
How many characters are contained
in this example text before end of file tag?
Replace the -c on the wc command with -w to count words or -l to count lines.
The shell uses shorthand notation for chaining commands together by redirecting STDOUT and STDIN. The vertical bar character (|) creates a pipeline of instructions. Arranging the commands in the correct order is critical:
ls -la | cut -c35-37 | grep A | sort -r
The file listing from the ls command is sliced vertically with the cut command to only yield columns 35 to 37. The grep command discards any lines that do not contain a capital letter 'A'. Finally, the sort command arranges the remaining lines alphabetically in reverse order.
Most punctuation symbols have a special meaning in the shell. We call them meta-characters. They may behave differently depending on the context:
• Command line parameters
• Describing file names
• Inside single quotes
• Inside double quotes
• Inside curly braces for variable substitution
• Inside back ticks for command substitution
• Inside dollar prefixed parenthesis for command substitution
• Conditional expressions between square brackets
• Regular expressions
Backslash symbols (\) placed in front of any meta-character deactivate any special treatment and render a literal character instead.
Variables store values for later use in the script. By convention, system provided variables are upper case and user defined variable names are lower case.
Assign values to a variable using the equals symbol:
Prefix the name with a dollar sign to access the value. Optional curly braces help the interpreter distinguish variables from the surrounding code.
Using a variable before it has been defined will halt your script with an error. Defined but empty variables are problematic if you expect them to contain a non-null value.
Curly brace substitution can apply checks and alter the outcome before substituting the value. Adding a colon-dash (:-) or equals (:=) after the variable name will choose a specific behaviour.
If a variable contains a meaningful value, that will be returned by the substitution. Undefined and null variables will yield the replacement text instead. This handles the undefined and null variables more gracefully and script will not halt:
The colon-dash substitution leaves the source variable unchanged. The colon-equals substitution will assign the replacement_string to the source variable if it was called for.
Process hierarchy and inheritance
Calling a command to action creates a new child process for it. Each process has a unique ID value. List the processes and their PID values with the ps command:
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Jan24 ? 00:00:06 /sbin/init
root 1677 1 0 Jan24 ? 00:00:00 /usr/sbin/ssh -D
root 29400 1677 0 09:55 ? 00:00:00 ssh: user [priv]
user 29511 29400 0 09:55 ? 00:00:00 sshd: [email protected]/0
user 29515 29511 0 09:55 pts/0 00:00:00 -bash
user 32536 29515 0 10:51 pts/0 00:00:00 ps -ef
Compare the (parent) PPID values with the PID values in the previous line to trace the provenance. The OS commences running with the init process. Observe the ps command in its own process at the end of the list.
Child processes only inherit user-defined variables from the parent if they have been prepared first with an export command. Special system variables are always available. Anything passed as a command line argument is accessible to the child process.
A sub-shell executes commands in a child process and substitutes the STDOUT result in its place. The older technique of using back-tick characters is superseded by using parenthesis with a leading dollar sign. Any valid command can be executed in the sub-shell, including running another script. Here is an example that assigns the contents of a data file to a variable:
This example should be used with great care because it could allow command injection if the source file contains valid commands:
Never take user input data at face value. Always clean and filter it to remove injected commands.
The loop constructs each determine how to continue looping in a different way. They are functionally similar to other languages but the syntax is slightly different.
|Iterator||Step through each item contained in a list with a for loop.|
|Step counter||Conventional for loop similar to C-Language.|
|Loop while false||While a condition is false, the loop continues.|
|Loop until false||While a condition is true, the loop continues.|
Making it runnable
When your script is ready to test, use the chmod command to apply the execute flag to it:
chmod +x your_new_script.sh
Without this, your script will not be allowed to run. Your account may need elevated privileges to do this.
Shell scripts are fundamental to building monitoring systems and diagnostic probes. Study the tools and practice writing simple scripts. Use online resources to extend your knowledge.
Because the edit-test cycle is so compact, shell scripts are useful for prototyping your monitoring architecture design before refactoring it into a compiled app.
We will use distributed shell scripts to implement a status screen to display performance measurements and flag problems on your systems.
You might also like...
Essential Guide: Delivering High Availability Cloud
Delivering high availability cloud for broadcast production and transmission environments requires engineers to think in terms of resilience from the very beginning of the design.
Vendor Spotlight: IHSE
At IHSE, KVM is king. Few companies know the value of a keyboard, video and mouse (KVM) system better than IHSE, which has been supplying compatible extenders and matrix switches for more than 40 years. In that time, a wide and…
Professional Live IP Video - Designing Networks
There’s a lot to consider when planning to incorporate uncompressed media into your live production particularly using SMPTE ST 2110, ST 2022-6 or AES67 streams. In this article, we will look at the network hardware, its architecture and future-proofing you s…
IP Monitoring & Diagnostics With Command Line Tools: Part 6 - Advanced Command Line Tools
We continue our series with some small code examples that will make your monitoring and diagnostic scripts more robust and reliable
Learning From The Experts At The BEITC Sessions at 2023 NAB Show
Many NAB Shows visitors don’t realize that some of the most valuable technical information released at NAB Shows emanates from BEITC sessions. The job titles of all but one speaker in the conference are all related to engineering, technology, d…