What does the following do exactly?
newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
if expr "x${newProg}" : 'x/' >/dev/null; then
prog="${newProg}"
else
progdir=`dirname "${prog}"`
prog="${progdir}/${newProg}"
fi
What does the following do exactly?
newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
if expr "x${newProg}" : 'x/' >/dev/null; then
prog="${newProg}"
else
progdir=`dirname "${prog}"`
prog="${progdir}/${newProg}"
fi
The first line uses expr to:
$newProg against the basic regular expression .* -> \(.*\)$ (anchored on both ends). That's anything with -> in it.newProg to the part of the original value matched by the capturing subexpression written in parentheses (the part after ->).The greedy matching semantics are such that this always captures and outputs the last such match, so there is never a -> in the output.
This would, for example, parse the output of ls -l on a symlink to find the target (given well-behaved filenames, etc, usual caveats).
The second line uses expr again to check whether the new value of newProg begins with a /, i.e., it represents an absolute path.
In the case where it does, prog is just set to that value. Otherwise, prog is set to a computed relative path using dirname on $prog, a variable not defined in this snippet. The effect will presumably be to construct a path relative to that original location.
If you are only targeting a more capable shell or environment than pure POSIX, there is likely to be a more reliable way of doing this than expr. readlink is a very commonly-available command also, which would save on parsing ls.