Query regarding portable script

Dear Experts,

I want to write a script which has to work on Solaris & Linux sytems.
The problem which i am facing is, there are commands whose options are different on both OS's. For example ping.

On Solaris i have to write:

ping $host 1

to check if the host is alive

On Linux i have to use following command

ping $host -c 1

One way to write generic script is

if [ `uname -s` == "SunOS" ]
then
OPT="1"
fi
if [ `uname -s` == "Linux" ]
then
OPT="-c 1"
fi

ping $host $OPT

The only problem with this approach is that for every set of options i have make OS specific check. Is there some better way of achieving same in shell scripts. In make i know sth like following works:

OPT.solaris="1"
OPT.linux="-c 1"
OPT=$(OPT.$(OSTYPE))

Is something like this possible in shell scripts also?

You could use arrays opt[].

Code like that is a nightmare to maintain. Consider writing two include files, i.e., files that get sourced when your script starts, which file is sourced depends on the OS.

Each sourced file has aliases for you problem commands:
The include file for LINUX has this line in it

alias ping1="/home/me/pinglinux.sh"
# /home/me/pinglinux.sh has this in it
ping $1 -c $2

In your main script you have

ping1 $host $count   # or whatever

The alias then becomes a wrapper for a ping call.

Depending on which shell you are using you could encapsulate the OS check into a function and set a global variable for the OS. In all further script parts you branch depending on that variable. The following is just a sketch:

#! /bin/ksh

function set_environment
{

case $(...some_check...) in
     solaris)
          OS="solaris"
          ;;

     linux)
          OS="linux"
          ;;

     *)
          OS="other"
          ;;

esac

}



function do_ping
{

target_host="$1"
return_value=0

case OS in
     solaris)
          ping $target_host 1
          return_value=$?
          ;;

     linux)
          ping -c 1 $target_host
          return_value=$?
          ;;

     *)
          print -u2 "ERROR: don't know how to ping on OS ${OS}"
          return_value=255
          ;;

esac

return $return_value
}

# ------------- main()

typeset -x OS=""

. set_environment

do_ping ...some_ip_address....
print - "ping returned $?"

exit 0

I hope this helps.

bakunin

Hi Jim,
Thanks for the reply. Even i agree sourcing in can be good solution.
As I am not expert in scripting so request you to elaborate on how i can source a file in my main script.

-Dhiraj

The . (dot) command reads in the contents of another file in the context of the current script.

. /path/to/include.sh

That's a dot, a space, and the name of the file to include.