Examples of Shell Script Wrappers: Enhancing Ping and Host Commands

Examples of Shell Script Wrappers: Enhancing Ping and Host Commands

12.03.2024
Author: HostZealot Team
2 min.
119

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. 

Related Articles