Examples of Shell Script Wrappers: Enhancing Ping and Host Commands
12:53, 12.03.2024
The transparency to the users of *nix command can be achieved with shell script wrappers. A wrapper is a shell function or shell script or an alias that contains a utility or system command.
Unix and Linux-like OSs can run 64-bit and 32-bit versions of apps. That means you can write a wrapper script and it will choose and execute the needed version of the 64bit or 32bit hardware platform. In a high-performance environment, it is possible to find 100s of wrapper scripts that are written in Python, Shell, and Perl in order to manage and submit jobs, troubleshoot, backups, set up the shared storage, get cluster usage, and more.
In this article, we decided to share our practical experience and explain how the shell wrapper is created to improve the primary troubleshooting tool.
Benefits of Shell Script Wrappers
- Start and call the needed job.
- Customization of *nix commands.
- Helpful in HPC, scientific research, and cluster environment.
- This is a perfect time-saving option.
- Passing default arguments to third-party apps or binaries.
- Wrappers are ideal for command or tools that need system controls, customized environment different settings, or job-submission parameter.
Example: Crafting a Shell Script Wrapper
The next shell script will start kvminit java app by redirecting logs to the file and setting up the environment of the system:
export JAVA_HOME=${JAVA_HOME:-/usr/java}
export CLASSPATH="/home/vivek/apps/java/class
exec ${JAVA_HOME}/bin/java kvminit "$@" &>/var/log/kvm/logfile
Another example of a wrapper script is functioning by stopping/starting the client or nfs server:
_me=${0##*/} # Server or client?
_server="/etc/init.d/rpcbind /etc/init.d/rpcidmapd /etc/init.d/nfslock /etc/init.d/nfs" # list of server init scripts
_client="/etc/init.d/rpcbind /etc/init.d/rpcidmapd /etc/init.d/nfslock" # list of client init scripts
_action="$1" # stop / start / restart
# activate all scripts with stop or start or restart
runme(){
local i="$1"
local a="$2"
for t in $i
do
$t $a
done
}
usage(){
echo "$_me stop|restart|start|reload|status";
exit 0
}
[ $# -eq 0 ] && usage
# main logic
case $_me in
nfs.server) runme "$_server" "$_action" ;;
nfs.client) runme "$_client" "$_action" ;;
*) usage
esac
Troubleshooting Tools: Ping and Host Commands
The basic troubleshooting tools for system administrators are host and ping.
- Host command is helpful with specifying DNS issues. It is possible to receive data about Domain name sys records for certain IPs and at the same time host names in order to troubleshoot DNS issues.
- Ping commands are needed for specifying connectivity between devices on the remote or local network.
Customized Wrapper for Ping
Sending ping request to a domain by removing protocol, username, urls:pass using system /bin/ping, looks like:
ping(){
local t="$1"
local _ping="/bin/ping"
local c=$(_getdomainnameonly "$t")
[ "$t" != "$c" ] && echo "Sending ICMP ECHO_REQUEST to \"$c\"..."
$_ping $c
}
Customized Wrapper for Host
For Dns lookups system /usr/bin/host use the following:
host(){
local t="$1"
local _host="/usr/bin/host"
local c=$(_getdomainnameonly "$t")
[ "$t" != "$c" ] && echo "Performing DNS lookups for \"$c\"..."
$_host $c
Utilizing the Original Ping and Host Commands
You need to create a shell script that is called $HOME/scripts/wrapper_functions.lib and fill in all 3 functions as in here:
_getdomainnameonly(){
local h="$1"
local f="${h,,}"
# delete protocol part of name
f="${f#http://}"
f="${f#https://}"
f="${f#ftp://}"
f="${f#scp://}"
f="${f#scp://}"
f="${f#sftp://}"
# delete username or/and username:password part of hostname
f="${f#*:*@}"
f="${f#*@}"
# delete all /foo/xyz.html*
f=${f%%/*}
# Reveal only domain name
echo "$f"
}
ping(){
local t="$1"
local _ping="/bin/ping"
local c=$(_getdomainnameonly "$t")
[ "$t" != "$c" ] && echo "Sending ICMP ECHO_REQUEST to \"$c\"..."
$_ping $c
}
host(){
local t="$1"
local _host="/usr/bin/host"
local c=$(_getdomainnameonly "$t")
[ "$t" != "$c" ] && echo "Performing DNS lookups for \"$c\"..."
$_host $c
}
After that edit $HOME/.bashrc by adding the next line:
source $HOME/scripts/wrapper_functions.lib
Save the file with the changes and also you may test whether everything works as needed.
Passing Command Line Arguments via Bash Shell Script Wrapper
_getdomainnameonly(){
local h="$1"
local f="${h,,}"
# delete protocol part of name
f="${f#http://}"
f="${f#https://}"
f="${f#ftp://}"
f="${f#scp://}"
f="${f#scp://}"
f="${f#sftp://}"
# delete username or/and username:password part of hostname
f="${f#*:*@}"
f="${f#*@}"
# delete all /foo/xyz.html*
f=${f%%/*}
# Reveal only domain name
echo "$f"
}
ping(){
local array=( $@ )
local len=${#array[@]}
local host=${array[$len-1]}
local args=${array[@]:0:$len-1}
local _ping="/bin/ping"
local c=$(_getdomainnameonly "$host")
[ "$t" != "$c" ] && echo "Sending ICMP ECHO_REQUEST to \"$c\"..."
# pass host and args
$_ping $args $c
}
host(){
local array=( $@ )
local len=${#array[@]}
local host=${array[$len-1]}
local args=${array[@]:0:$len-1}
local _host="/usr/bin/host"
local c=$(_getdomainnameonly "$host")
[ "$t" != "$c" ] && echo "Performing DNS lookups for \"$c\"..."
$_host $args $c
}
To Sum Up
We have shared functions and a small script that can perform operations to achieve the needed results. To create other functionality, you should have existing binaries and reuse code.