Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Could this be written in a more portable way?

3 views
Skip to first unread message

Dave

unread,
Jun 8, 2008, 8:31:29 AM6/8/08
to
I am trying to help do some work on Sage

http://www.sagemath.org/

and have tried to compile it on an HP-UX box which has bash version
2.04. The following is in a script

#!/usr/bin/env bash


...

# Make sure that the install worked, despite whatever the error
# code of build was.
if [ -f $DYLIB_NAME -a -f $SAGE_LOCAL/lib/libreadline.a ]; then
# Fix permissions.
chmod 755 $SAGE_LOCAL/lib/libreadline.*
chmod 755 $SAGE_LOCAL/lib/libhistory.*
exit 0
else
echo "Readline's build claims to have finished, but files that should
have been built weren't."
exit 1
fi

Basically the line

"if [ -f $DYLIB_NAME -a -f $SAGE_LOCAL/lib/libreadline.a ]; then"

is failing to work properly - the script thinks the files are not
present, even thougth they are. I suspect (but have not verified) this
is a problem with bash being quite old.

Could this be written in a more portable way, which ideally will work
with any POSIX shell, but it not too dependant on a recent version of bash?

Dave

Stephane Chazelas

unread,
Jun 8, 2008, 9:36:46 AM6/8/08
to
2008-06-08, 13:31(+01), Dave:
[...]

> #!/usr/bin/env bash
>
>
> ...
>
> # Make sure that the install worked, despite whatever the error
> # code of build was.
> if [ -f $DYLIB_NAME -a -f $SAGE_LOCAL/lib/libreadline.a ]; then
> # Fix permissions.
> chmod 755 $SAGE_LOCAL/lib/libreadline.*
> chmod 755 $SAGE_LOCAL/lib/libhistory.*
> exit 0
> else
> echo "Readline's build claims to have finished, but files that should
> have been built weren't."
> exit 1
> fi
[...]

This script is POSIX, though it has a number of small issues in
it, so you can get rid of the #! line.

if [ -f "$DYLIB_NAME" ] &&
[ -f "$SAGE_LOCAL/lib/libreadline.a ]; then
chmod -- a=rx,u+w "$SAGE_LOCAL"/lib/libreadline.* \
"$saGE_LOCAL"/lib/libhistory.*
exit # (with exit status of chmod)
else
echo >&2 "..."
exit 1
fi

In POSIX shell, you can't guarantee the behavior of "[" if there
are more than three arguments, so -a and -o should be avoided
and several "[" command run instead. It's unlikely to cause
problem in your case, but it's a good habit to have in any case.

Leaving a variable unquoted is the split+glob operator in
shells. It's unlikely to be the source of the problem in your
case unless some of variables contain some blanks or wildcard
characters or you changed $IFS

Error messages should be displayed on stderr.

The GNU utilities accept options anywhere in their arguments
(unless called with POSIXLY_CORRECT) before a "--" one. So
anything that must not be taken as option must be placed after
"--". Again, highly unlikely to cause problem in your case.

[...]


> "if [ -f $DYLIB_NAME -a -f $SAGE_LOCAL/lib/libreadline.a ]; then"
>
> is failing to work properly - the script thinks the files are not
> present, even thougth they are. I suspect (but have not verified) this
> is a problem with bash being quite old.

[...]

unlikely to be a shell issue. bash 2.04 is as able to interpret
it as any other version or any other POSIX shell. Could be that
$DYLIB_NAME or $SAGE_LOCAL contains weird invisble characters.

Also note that on HPUX, shared libraries have a ".sl" extension
as opposed to ".so" in other systems.

--
Stéphane

Dave

unread,
Jun 8, 2008, 9:50:34 AM6/8/08
to
Stephane Chazelas wrote:

> This script is POSIX, though it has a number of small issues in
> it, so you can get rid of the #! line.
>
> if [ -f "$DYLIB_NAME" ] &&
> [ -f "$SAGE_LOCAL/lib/libreadline.a ]; then
> chmod -- a=rx,u+w "$SAGE_LOCAL"/lib/libreadline.* \
> "$saGE_LOCAL"/lib/libhistory.*
> exit # (with exit status of chmod)
> else
> echo >&2 "..."
> exit 1
> fi
>
> In POSIX shell, you can't guarantee the behavior of "[" if there
> are more than three arguments, so -a and -o should be avoided
> and several "[" command run instead. It's unlikely to cause
> problem in your case, but it's a good habit to have in any case.

Thank you.

> Leaving a variable unquoted is the split+glob operator in
> shells. It's unlikely to be the source of the problem in your
> case unless some of variables contain some blanks or wildcard
> characters or you changed $IFS
>
> Error messages should be displayed on stderr.

Good point. I find it hard to find errors in this code, since one can't
redirect the output to /dev/null and be left with only the errors.
Instead, it redirects the errors too.

How does one echo things to stderr in a script though? I'd know how to
do it in a C program, but not on a shell script.

> The GNU utilities accept options anywhere in their arguments
> (unless called with POSIXLY_CORRECT) before a "--" one. So
> anything that must not be taken as option must be placed after
> "--". Again, highly unlikely to cause problem in your case.
>
> [...]
>> "if [ -f $DYLIB_NAME -a -f $SAGE_LOCAL/lib/libreadline.a ]; then"
>>
>> is failing to work properly - the script thinks the files are not
>> present, even thougth they are. I suspect (but have not verified) this
>> is a problem with bash being quite old.
> [...]
>
> unlikely to be a shell issue. bash 2.04 is as able to interpret
> it as any other version or any other POSIX shell. Could be that
> $DYLIB_NAME or $SAGE_LOCAL contains weird invisble characters.

OK, thank you for your advice. I will try to debug this some more.

> Also note that on HPUX, shared libraries have a ".sl" extension
> as opposed to ".so" in other systems.

Yes, the .sl confused me for quite a while. I'm used to Solaris, not HP-UX

Stephane CHAZELAS

unread,
Jun 8, 2008, 10:18:04 AM6/8/08
to
2008-06-08, 14:50(+01), Dave:
[...]

>> else
>> echo >&2 "..."
>> exit 1
>> fi
[...]

> Good point. I find it hard to find errors in this code, since one can't
> redirect the output to /dev/null and be left with only the errors.
> Instead, it redirects the errors too.
>
> How does one echo things to stderr in a script though? I'd know how to
> do it in a C program, but not on a shell script.
[...]

echo ... >&2

Note that "echo" behavior is unspecified if its arguments may
contain backslashes or start with "-".

You may want to do something like:

die() {
printf >&2 '%s: FATAL: %s\n' "$0" "$1"
exit 1
}

Then:

[ -f ... ] &&
[ -f ... ] ||
die "Missing files"

chmod -- a=rx,u+w ...

[...]
>> unlikely to be a shell issue. bash 2.04 is as able to interpret
>> it as any other version or any other POSIX shell. Could be that
>> $DYLIB_NAME or $SAGE_LOCAL contains weird invisble characters.
>
> OK, thank you for your advice. I will try to debug this some more.

[...]

Try running your script with

bash -x ./your-script 2>&1 | sed -n l

--
Stéphane

0 new messages