use portable "command -v" to detect installed programs, part 4

The "which" utility is not guaranteed to be installed either, and if it
is, its behavior is not portable either. This means that when various
programs are installed, the `which` check will report a fatal error
because the which tool did not exist and the shell returned a nonzero
status when attempting to fork+exec. If it did exist, it might not be an
implementation of `which` that returns nonzero when commands do not
exist.

The general scripting suggestion is to use the "command -v" shell
builtin; this is required to exist in all POSIX 2008 compliant shells,
and is thus guaranteed to work everywhere.

For some in-depth discussions on the topic, see:
- https://mywiki.wooledge.org/BashFAQ/081
- https://unix.stackexchange.com/questions/85249/why-not-use-which-what-to-use-then/85250#85250

Examples of open-source shells likely to be installed as /bin/sh on
Linux, which implement the 15-year-old standard: ash, bash, busybox,
dash, ksh, mksh and zsh.

This commit updates a couple build scripts to not rely on fixed paths
calculated upfront. Checking the location of a tool with cmd=$(which
foo) just to run it as `$cmd` is pointless. It's exactly equivalent to
run it as `foo`, but less error-prone and easier to read.

For one of the scripts, it also simplifies checking for their existence.
Personally, I am skeptical it even makes sense to check at all. POSIX
mandates they exist, and it's exceedingly unlikely they will not be
installed. However, unlike the shell interpreter itself, we don't *know*
they are installed, so leave the existing checks in but simplified.

Change-Id: I4703c1165eb3a5aeb45fbab18df3222e8f5f9551
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160665
Tested-by: Jenkins
Tested-by: Ilmari Lauhakangas <ilmari.lauhakangas@libreoffice.org>
Reviewed-by: Ilmari Lauhakangas <ilmari.lauhakangas@libreoffice.org>
This commit is contained in:
Eli Schwartz 2023-12-13 00:01:39 -05:00 committed by Ilmari Lauhakangas
parent cf02724e51
commit 2a5ff80264
2 changed files with 14 additions and 27 deletions

View file

@ -10,13 +10,11 @@
# Run the script in the core directory to remove all tooltip_markup # Run the script in the core directory to remove all tooltip_markup
# properties from the .ui files # properties from the .ui files
SED_BIN=`which sed`
CUT_BIN=`which cut`
LOG_FILE="modified-$(date +%s).log" LOG_FILE="modified-$(date +%s).log"
removeTooltipMarkup() removeTooltipMarkup()
{ {
LINE=$(grep -n "<property name=\"tooltip_markup\"" $1 | $CUT_BIN -f 1 -d ':') LINE=$(grep -n "<property name=\"tooltip_markup\"" $1 | cut -f 1 -d ':')
TEXT=$(grep "<property name=\"tooltip_markup\"" $1) TEXT=$(grep "<property name=\"tooltip_markup\"" $1)
grep -v "<property name=\"tooltip_markup\"" $1 > temp && mv temp $1 grep -v "<property name=\"tooltip_markup\"" $1 > temp && mv temp $1
echo "removed $TEXT from $1 at line $LINE" >> $LOG_FILE echo "removed $TEXT from $1 at line $LINE" >> $LOG_FILE
@ -24,8 +22,8 @@ removeTooltipMarkup()
changeTooltipMarkup() changeTooltipMarkup()
{ {
LINE=$(grep -n "<property name=\"tooltip_markup\"" $1 | $CUT_BIN -f 1 -d ':') LINE=$(grep -n "<property name=\"tooltip_markup\"" $1 | cut -f 1 -d ':')
$SED_BIN "s/tooltip_markup/tooltip_text/g" $i > temp && mv temp $1 sed "s/tooltip_markup/tooltip_text/g" $i > temp && mv temp $1
echo "renamed tooltip_markup from $1 at line $LINE" >> $LOG_FILE echo "renamed tooltip_markup from $1 at line $LINE" >> $LOG_FILE
} }

View file

@ -43,24 +43,13 @@ ModelineReplace="false"
function SetEnvironment() function SetEnvironment()
{ {
if [ -n "$(which tail)" ] && [ -n "$(which head)" ]; then if ! command -v tail || ! command -v head; then
{
headCMD=$(which head)
tailCMD=$(which tail)
}
else
{
echo "Missing head or tail, exiting..." echo "Missing head or tail, exiting..."
exit 1 exit 1
}
fi fi
if [ -n "$(which find)" ]; then if ! command -v find; then
findCMD=$(which find)
else
{
echo "Missing find, exiting..." echo "Missing find, exiting..."
exit 1 exit 1
}
fi fi
} }
@ -72,15 +61,15 @@ function EditFile()
FileToEdit="$1" FileToEdit="$1"
currentFirstLine=$($headCMD -1 "$FileToEdit") currentFirstLine=$(head -1 "$FileToEdit")
currentLastLine=$($tailCMD -1 "$FileToEdit") currentLastLine=$(tail -1 "$FileToEdit")
case "$ModelineReplace" in case "$ModelineReplace" in
"true" ) "true" )
if [ "${currentFirstLine:0:6}" = "${FirstLine:0:6}" ]; then if [ "${currentFirstLine:0:6}" = "${FirstLine:0:6}" ]; then
{ {
echo "$FirstLine" > "$FileToEdit".new echo "$FirstLine" > "$FileToEdit".new
$tailCMD -n +2 "$FileToEdit" >> "$FileToEdit".new tail -n +2 "$FileToEdit" >> "$FileToEdit".new
} }
fi fi
if [ -e "$FileToEdit.new" ]; then if [ -e "$FileToEdit.new" ]; then
@ -90,7 +79,7 @@ function EditFile()
fi fi
if [ "${currentLastLine:0:6}" = "${LastLine:0:6}" ]; then if [ "${currentLastLine:0:6}" = "${LastLine:0:6}" ]; then
{ {
$headCMD -n -1 "$FileToEdit" > "$FileToEdit".new head -n -1 "$FileToEdit" > "$FileToEdit".new
echo "$LastLine" >> "$FileToEdit".new echo "$LastLine" >> "$FileToEdit".new
} }
fi fi
@ -161,7 +150,7 @@ done
# This gets rid of the final " -a " in the find argument list # This gets rid of the final " -a " in the find argument list
findArgs=(${findArgs:0:(${#findArgs}-3)}) findArgs=(${findArgs:0:(${#findArgs}-3)})
for file in $($findCMD "${findArgs[@]}"); do for file in $(find "${findArgs[@]}"); do
EditFile "$file" EditFile "$file"
echo "Completed: " "$file" echo "Completed: " "$file"
done done