bourne shell if [ -e $directory/file.$suffix ]
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.
Related videos on Youtube
BitsOfNix
Working mainly with Solaris and Linux. System administration!
Updated on September 18, 2022Comments
-
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 theif
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 over 11 yearsOn 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 standardsh
. -
BitsOfNix over 11 yearsI need to maintain what is already previously being use and that sticks me to /bin/sh or perl.
-
-
ssola over 11 yearsThe standard test command supports the
-e
flag, and that command is what standardsh
should support. Your answer is not correct forsh
in general, but only very old nonstandardsh
s on Solaris. -
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 over 11 yearsThanks @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.