bourne shell if [ -e $directory/file.$suffix ]

6,298

The Bourne shell is somewhat of an antique. The Solaris version doesn't have the -e operator for the test (a.k.a. [) builtin that was introduced somewhat late in the life of the Bourne shell¹ and enshrined by POSIX.

As a workaround, you can use -f to test for the existence of a regular file, or -r if you aren't interested in unreadable files.

Better, change #!/bin/sh to #!/usr/xpg4/bin/sh or #!/bin/ksh so as to get a POSIX shell.

Beware that [ $option -eq 9 ] is probably not right: -eq is a numerical comparison operator, but $option isn't really numeric — it's a date. On a 32-bit machine, when 201301271355 is interpreted as a number, it is taken modulo 232. It so happens that no date in the 21st century is very close to 0 modulo 232, but relying on this is very brittle. Make this [ "$option" = 9 ] instead.

As a general shell programming principle, always put double quotes around variable and command substitutions: "$foo", "$(foo)". If you don't, the shell splits the result at each whitespace character and treats each resulting word as a filename wildcard pattern. So an unprotected $foo is only safe if the value of foo does not contain any whitespace or \[?*. Play it safe and always use double quotes (unless you intend the splitting and pattern matching to happen).

¹ Or was it a ksh addition never ported to Bourne? I'm not sure.

Share:
6,298

Related videos on Youtube

BitsOfNix
Author by

BitsOfNix

Working mainly with Solaris and Linux. System administration!

Updated on September 18, 2022

Comments

  • BitsOfNix
    BitsOfNix almost 2 years
    #!/bin/sh
    CONFIG_DIR="/var/opt/SUNWldm/"
    read option
    if [ $option -eq 9 ]; then
            ret=1
    elif [ -e ${CONFIG_DIR}file.xml.${option} ]; then
            echo "TRUE"
    fi
    

    I have the above code in a while loop to present a list of options. Unfortunately I'm having problems with the elfi statement.

    From: IF for Beginners the -e returns true if the file exists.

    I've double checked the syntax and even running the script in debug mode (I put set -x at the beginning of this script and could see that the replacement in the if is done properly as seen inline:

    + [ 201301271355 -eq 9 ]
    + [ -e /var/opt/SUNWldm/file.xml.201301271355 ]
    ./ldm_recover.sh: test: argument expected
    

    I've been searching so far and haven't found a reason for failing, any ideas what I'm doing wrong?

    • Stéphane Chazelas
      Stéphane Chazelas over 11 years
      On Solaris, don't use /bin/sh, use /usr/xpg4/bin/sh to get a standard shell. /bin/sh is only for backward compatibility for old scripts that rely on /bin/sh being a Bourne shell and not a standard sh.
    • BitsOfNix
      BitsOfNix over 11 years
      I need to maintain what is already previously being use and that sticks me to /bin/sh or perl.
  • ssola
    ssola over 11 years
    The standard test command supports the -e flag, and that command is what standard sh should support. Your answer is not correct for sh in general, but only very old nonstandard shs on Solaris.
  • BitsOfNix
    BitsOfNix over 11 years
    @kojiro you will notice that I'm using #!/bin/sh, do the answer is indeed correct for this environment, I could agree if I would be using the other sh available like /usr/xpg4/bin/sh.
  • BitsOfNix
    BitsOfNix over 11 years
    Thanks @Gilles for the recommendation and the effort explaining it. But in this case, the $option is indeed a integer that is taken from the files names, presented in a menu and then given "copy/paste" or insert manually in the read option. I'll update the script with the '"' so I don't get surprises if a user makes a mistake with spaces. Thanks a lot.