6

I occasionally do work on an older Solaris machine whose default version of grep is non-POSIX-compliant. This causes problems in my rc files because the default grep on the machine doesn't support the options I need.

This is a machine at my place of work, and I'm not an admin; so I can't just install newer/better versions of commands as I see fit. However, I notice that the machine does have a suitable XPG version of grep at /usr/xpg4/bin/grep.

Obviously, I can solve the problem (for Solaris) in my rc files with:

alias grep='/usr/xpg4/bin/grep'

But what about machines where this isn't necessary? My goal is to have a single rc file for each shell that I can drop into any Unix-like system and have it just work.

This got me thinking...

  1. Is there ever a case where I wouldn't want to use the XPG version of a command?
    • If so, when?
  2. Couldn't I just blindly add /usr/xpg4/bin/ to the beginning of $PATH in my rc files on all machines and forgo aliasing individual commands to their XPG* versions?
    • Or will this cause problems for some commands?
  3. Is it the case that /usr/xpg4/bin/ exists only on machines where it is "necessary"?
    • I ask because I notice that /usr/xpg4/bin/ doesn't exist on my Ubuntu machine.

So to sum up, is this a good a idea?

if [ -d "/usr/xpg4/bin" ]; then
  #Place XPG directory at beginning of path to always use XPG version of commands
  export PATH="/usr/xpg4/bin:$PATH"
fi

If not, why not?

3

Several commercial Unix systems have backward-compatible utilities in /bin and /usr/bin, and a directory such as /usr/xpg4/bin that contain POSIX-compliant utilities. That way, old applications can stick to the old PATH with just /bin and /usr/bin, and newer applications use a PATH with the POSIX utilities first. Unless you need backward compatibility with the 1980s utilities from that Unix system, you're better served by using the POSIX utilities.

In my .profile, I put the following directories ahead of /bin and /usr/bin, if they exist:

/bin/posix
/usr/bin/posix
/usr/xpg6/bin
/usr/xpg4/bin
/usr/xpg2/bin

I think this covers at least Solaris, Tru64 (aka Digital Unix aka OSF/1) and HP-UX.

Rather than determine the PATH automatically, you should be able to find a suitable PATH for POSIX-relying applications by calling the getconf utility:

PATH=$(getconf PATH)

Some systems such as *BSD and Linux only ship POSIX-compliant utilities, so they're in the usual directories (/bin, /usr/bin) and there's no need for any separate directory.

1

First, don't use the alias version you depicted in your question; this is certainly the worst option you have. Also don't append that XPG4 path hard-coded for all platforms.

On Solaris you are generally much better served (to say the least) if you define /usr/xpg4/bin in your PATH before the other system bin directories. I dare to say that the XPG4 standard version of the tools is generally the better choice on that platform. (One prominent other example is "broken awk" on Solaris.) I'd certainly suggest to define this XPG4 PATH just for the Solaris platforms; so you could interrogate the platform and conditionally set it in your profile.

I'd probably test against the output of uname, but I also don't see a problem with testing the existence of the /usr/xpg4/bin directory as you did.

  • Is Solaris the only OS where I need to worry about this, then? – Sildoreth Apr 28 '15 at 12:40
  • @Sildoreth; Given how many Unix variants there are, this is a very broad question that I dare not to answer generally. But Solaris is the only one that I heard of and it's the only one widely known to have that problem with its standard bin directories and the programs therein. - Let me add; usually you'd know the systems you are developing for, and (hopefully) also test your software on those systems. In case of doubt, I'd just check those systems to be sure. – Janis Apr 28 '15 at 13:00
0

Depending on the shell used, you may have a parameter that you could test; like OSTYPE, stuffing OS specific things in there.

if [[ $OSTYPE == solaris* ]]; then
  here be dragons
fi

Or if you have a few different OSs

case $OSTYPE in
  freebsd*|solaris*)
    export MANWIDTH=tty
  ;;
  openbsd*)
    export "PKG_PATH=http://mirror.team-cymru.org/pub/OpenBSD/$(uname -r)/packages/$(uname -p)"
  ;;
esac

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.