5
#!/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?

  • 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. – Stéphane Chazelas Jan 28 '13 at 12:10
  • I need to maintain what is already previously being use and that sticks me to /bin/sh or perl. – BitsOfNix Jan 29 '13 at 7:31
6

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.

  • 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. – BitsOfNix Jan 29 '13 at 7:34
0

Well this was easier than I though:

It seems that the -e operator for the if is not defined in bourne shell (sh) but only in bourne again shell (bash).

I replaced the if [ -e ... by if [ -r ... and it's working.

  • 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. – kojiro Jan 29 '13 at 0:40
  • @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 Jan 29 '13 at 7:30

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.