1

I have a bunch of ksh and csh scripts that need to be updated to run in different *nix flavors (red hat linux, hp ux, solaris). The shells are mounted in the home of each of our servers and we need to have them working in each env.

We have issues with some particular commands that are not found under linux. For example scripts use nawk, which should be replaced by gawk on linux.

Scripts also use /usr/xpg4/bin/grep because on solaris grep can't take the -q (quiet) option, but linux's grep can and in this env /usr/xpg4/bin/grep doesn't exist.

I don't want to touch every script, so I'm looking for a more global solution.

I've tried to setup aliases, that works. But only in interactive mode. Looks like it isn't advised to use aliases in scripts...

I can add symlink in the system dirs but then I'll need admin rights to manage this 'mocking' setup and the our setup is not portable anymore...

I'm not used to system admin, so I can miss a standard solution for this kind of need.

What can I do to have portable script without to rewrite them all ?

1
  • Use the same base system; Touch all the scripts and include switches; setup symlinks etc. so it does feel similar.
    – Seth
    Oct 26, 2016 at 10:46

2 Answers 2

2

The right approach is to stick to POSIX compliant commands (i.e. use awk, not nawk or gawk, grep, not /usr/xpg4/bin/grep), options and syntax and set your PATH that way:

PATH=$(getconf PATH):$PATH

or on Solaris if using the legacy Bourne shell:

PATH=`getconf PATH`:$PATH

and that's it, your scripts launched for there should run unmodified. Avoid using the #!/bin/sh shebang though, which despite popular belief is not POSIX compliant. Just use no shebang at all. You might use command -v sh so see what POSIX shell is available on your machine.

However, it looks like you want to keep your non portable scripts unchanged. Then you might keep the previously suggested approach for commands using the POSIX syntax and add a front end for the non portable commands to be handled on other OSes. As your scripts are using either Bourne or Csh style shells, aliases and functions won't be portable so better to use your own wrapper scripts library that you put in front of your PATH. For example:

sh / ksh / bash / ... :

PATH=~/bin:`getconf PATH`:$PATH 

csh :

set path = ( ~/bin `getconf PATH` $path)

-

mkdir -p ~/bin
cd ~/bin
cat > awk <<%
#!/bin/sh
PATH=`getconf PATH`:$PATH awk "$@"
%
ln -s awk nawk
ln -s awk gawk
2
  • this won't change the fact that there are part in code that call nawk wich is not supported by the linux env. For the shebang, it's too late: scripts contains it and it is required because some scripts are cshell, some others are kshell and the main shell is bash...
    – Guillaume
    Oct 26, 2016 at 11:33
  • I'll probably use this solution for the grep issue, as there's no single solution for my issue.
    – Guillaume
    Oct 26, 2016 at 12:18
1

In such case I use variables

AWK=awk
GREP=grep

then test for operating system

if [ $(uname -s) == "SunOS" ]
then
  AWK=/usr/bin/nawk
  GREP=/usr/xpg4/bin/grep
fi

(repeat for redhat, suse, hp-ux, aix)

and use variable after

if $GREP -q whatever /some/file
then
   $AWK -F: '{....}' /some/file
fi

this way I have only one script but usable in all hosts.

1
  • I really don't want to add this mess in all the scripts
    – Guillaume
    Oct 26, 2016 at 11:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .