From: Stephane CHAZELAS on
2010-01-8, 09:38(-08), David Kirkby:
[...]
> 1) Can you tell me if the following is perfectly safe:
>
> if [ ! -x "$SAGE_LOCAL/bin/testcc.sh" ] || [ ! -x "$SAGE_LOCAL/bin/
> testcxx.sh" ] ; then
> echo "testcc.sh and/or testcxx.sh either do not exist, or are not
> executable"
> exit 1
> fi

You can't get any safer than that.

However note that the files may exist and not be accessible (so
that the test above can't decide). So instead of "do not exist",
you could say "cannot be found".

Also, it's a good idea to output error messages on stderr, so:

echo >&2 "..."

> $SAGE_LOCAL is a directory (in my case /export/home/drkirkby/
> sage-4.3.1.alpha1/local). I happen to know that $SAGE_LOCAL will have
> no spaces in it, but in general would the above work if the path has
> spaces? Let's for example assume it was "/export/home/drkirkby/this is
> an alpha release of sage 4.3.1". Can I be sure the above will always
> work?

Yes, it shouldn't have any problem with any character, and if it
has, it's a bug and you can't get any better.

>
> Is:
>
> if [ ! -x ""$SAGE_LOCAL"/bin/testcc.sh" ] || [ ! -x ""$SAGE_LOCAL"/bin/
> testcxx.sh" ] ; then
> echo "testcc.sh and/or testcxx.sh either do not exist, or are not
> executable"
> exit 1
> fi
>
> better or not?

It's worse, it's "" followed by $SAGE_LOCAL unquoted, so subject
to word splitting and filename generation.

[...]
> C_compiler=`"$(SAGE_LOCAL)"/bin/testcc.sh $CC`
> C_PLUS_PLUS_compiler=`"$(SAGE_LOCAL)"/bin/testcxx.sh $CXX`
>
>
> but that results in errors when the script is run.
>
> /export/home/drkirkby/sage-4.3.1.alpha1/local/bin/sage-spkg: line 317:
> SAGE_LOCAL: command not found


$(...) is command substitution and is equivalent to `...` in
POSIX shells (you must be confusing with $(...) in Makefiles),
you want:

C_compiler=`"$SAGE_LOCAL"/bin/testcc.sh "$CC"`

(you've got no reason not to quote $CC as far as I can tell,
unless you want it to be split).

[...]
> C_PLUS_PLUS_compiler=`$SAGE_LOCAL/bin/testcxx.sh $CXX`
>
> but I'm concerned that in general that might not be reliable if
> SAGE_LOCAL had spaces or other difficult characters.

Only quoting prevents word splitting (or you could set $IFS to
the empty string), quoting also prevents filename generation
(which you can disable globally with "set -f"), and the removal
of empties (which you can't disable globally).

[...]
> if [ "$C_compiler" != "$C_PLUS_PLUS_compiler" ] ; then
> echo ""
> echo "ERROR: You have different C and C++ compilers."
> echo "ERROR The C compiler is $C_compiler, the C++ compiler is
> $C_PLUS_PLUS_compiler"
[...]
> fails to produce the expected result, as the output from the script
> is:
[...]
> ERROR The C compiler is Sun_Studio, the C++ compiler is Sun_Studio
> ERROR: This mixture can not be used to build Sage
> ERROR: Ensure both compilers are the same
[...]

Possibly $C_PLUS_PLUS_compiler has trailing spaces, or any one
of them have invisible characters. Try piping the output of the
script into "sed -n l"


--
St�phane
From: Rakesh Sharma on
On Jan 8, 11:59 am, David Kirkby <drkir...(a)gmail.com> wrote:
> I've seen alo of the following in scripts,
>
> if [ $foo = "sun" ]  && [  $bar = "moon"  ] ; then
>
> if [ "$foo" = "sun" ]  && [ $bar = "moon" ] ; then
>
> if [ "x$foo" = "xsun" ]  && [ "x$bar" = "xmoon" ] ; then
>
> if [ x$foo = "xsun" ]  && [  x$bar = "xmoon" ] ; then
>
> Also, sometime {  and } are used.
>
> What is the best way to compare things in shell scripts?


case "$foo/$bar" in
'sun/moon' )
echo .............
;;
esac
From: bsh on
David Kirkby <drkir...(a)gmail.com> wrote:
> if [ $foo = "sun" ] && [ $bar = "moon" ] ; then
> if [ "$foo" = "sun" ] && [ $bar = "moon" ] ; then
> if [ "x$foo" = "xsun" ] && [ "x$bar" = "xmoon" ] ; then
> if [ x$foo = "xsun" ] && [ x$bar = "xmoon" ] ; then
> Also, sometime { and } are used.
> What is the best way to compare things in shell scripts?

I'm surprised that nobody thus so far has contributed
the obligatory comment, "Don't use the '[ ... ]' syntax."
You fail to give the shell you work in, and perhaps
this shell is indeed ksh(1), which means you can use
the newer "[[ ... ]]" syntax -- there is a good reason
why the older syntax is deprecated, and the new
one added!

See my previous post at:

http://groups.google.com/group/comp.unix.shell/msg/d3076c3ca825c1e3

There are unavoidable pathological cases involving
"[ ... ]" that are addressed in "[[ ... ]]", which
uses a different algorithm to discrimate parameters
versus operators. In _general_, double-quoting
parameters is no longer necessary, nor is explicit
variable substitution with integer-type variables.

So, the _best_ syntax is:

[[ $foo = sun && $bar = moon ]] && ...

BTW, the "=" operator takes a _regex_ as the RHS,
which allows much flexibility.

=Brian
From: Sven Mascheck on
bsh wrote:

> There are unavoidable pathological cases involving
> "[ ... ]" that are addressed in "[[ ... ]]", which
> uses a different algorithm to discrimate parameters
> versus operators.

I guess you mean "unavoidably" pathological
(the test operators -a and -o).

Otherwise all other shells would have had to "catch up"
long time ago... :-)
From: Chris F.A. Johnson on
On 2010-01-09, bsh wrote:
> David Kirkby <drkir...(a)gmail.com> wrote:
>> if [ $foo = "sun" ] && [ $bar = "moon" ] ; then
>> if [ "$foo" = "sun" ] && [ $bar = "moon" ] ; then
>> if [ "x$foo" = "xsun" ] && [ "x$bar" = "xmoon" ] ; then
>> if [ x$foo = "xsun" ] && [ x$bar = "xmoon" ] ; then
>> Also, sometime { and } are used.
>> What is the best way to compare things in shell scripts?
>
> I'm surprised that nobody thus so far has contributed
> the obligatory comment, "Don't use the '[ ... ]' syntax."

It's not obligatory at all; it's misguided.

> You fail to give the shell you work in, and perhaps
> this shell is indeed ksh(1), which means you can use
> the newer "[[ ... ]]" syntax -- there is a good reason
> why the older syntax is deprecated, and the new
> one added!

There is no good reason not to use the standard syntax; it is not
deprecated by any authority.

> See my previous post at:
>
> http://groups.google.com/group/comp.unix.shell/msg/d3076c3ca825c1e3
>
> There are unavoidable pathological cases involving
> "[ ... ]" that are addressed in "[[ ... ]]", which
> uses a different algorithm to discrimate parameters
> versus operators. In _general_, double-quoting
> parameters is no longer necessary, nor is explicit
> variable substitution with integer-type variables.
>
> So, the _best_ syntax is:
>
> [[ $foo = sun && $bar = moon ]] && ...
>
> BTW, the "=" operator takes a _regex_ as the RHS,
> which allows much flexibility.

99% of the time, file-globbing patterns are adequate, and they are
much more straightforward than regexes.

--
Chris F.A. Johnson, author <http://shell.cfajohnson.com/>
===================================================================
Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)
===== My code in this post, if any, assumes the POSIX locale =====
===== and is released under the GNU General Public Licence =====