I want to get the output of the following shell command into a make variable:
# The following is used as a path containing the following directories named:
# install-20240714, install-20240715, install-20240716.
# The directories are contained in ${DOWNLOAD_PATH}/${PROVIDER_NAME}.
# From this, the output of the command is the most recent numeric date
# which I want to refer to, later on, in the same recipe.
DOWNLOAD_PATH=/tmp;
PROVIDER_NAME=tug.org;
pkgRelDate=`ls ${DOWNLOAD_PATH}/${PROVIDER_NAME}
| tail -n 1
| awk '{match($0, /[0-9]{8}/, date); print date[0]}'`;
cat ${TEMPLATE_NAME} > ${pkgRelDate}.pfl
TEMPLATE_NAME is a plain text file that needs to be outputed into ${pkgRelDate}.pfl
.
I tried to echo the output of the ls command but the value of the variable seems empty.
What am I missing?
10
I’m not really sure what you want to do because you haven’t actually shown a complete rule, just a bunch of small snippets that can be combined in many ways in a makefile. But, remember that the entirety of a recipe runs inside the shell. So you can’t set makefile variables from within a recipe: you can only set shell variables from within a recipe. And when you reference shell variables in a recipe, you must always use $$
not $
.
Here’s a way to get what you want (based on the comments and examples in your question) using GNU Make functions, outside of any recipe:
# This all appears OUTSIDE of a make recipe and sets MAKE variables
DOWNLOAD_PATH = /tmp
PROVIDER_NAME = tug.org
pkgRelDate = $(patsubst install-%,%,$(lastword $(sort $(notdir $(wildcard ${DOWNLOAD_PATH}/${PROVIDER_NAME}/install-*)))))
# Now you can use this MAKE variable in a recipe
myrule:
cat ${TEMPLATE_NAME} > ${pkgRelDate}.pfl
If you must perform this check inside a recipe (because, for example, the files you want to check in ${DOWNLOAD_PATH}/${PROVIDER_NAME}
are created by the recipe where they are used) then you have to use shell commands:
myrule:
<do stuff that generates the install-files>
# This creates a SHELL variable in this recipe
pkgRelDate=`cd /tmp/tug.org; ls -1
| tail -n 1
| sed 's/install-//'`;
cat ${TEMPLATE_NAME} > "$$pkgRelDate".pfl
2
Thank you all for the support. I suggest the following solution taking all of your inputs into consideration.
Here’s a MRE:
#!/usr/bin/env -S /usr/bin/make -f
# ##############################################################################
# How to store returned output of shell command into a variable from a make
# recipe to refer to it successively?
.ONESHELL:
install:
mkdir -p ${DownloadPath}/${ProviderName}
tar -C ${DownloadPath}/${ProviderName} -zxf ${DownloadPath}/${DistName}
dirFind=$$(find ${DownloadPath}/${ProviderName} -name 'install-tl-*' -type d)
for dirPath in $$(echo "$${dirFind}" | tac); do
cat ${CfgPath}/${TemplateName} > $${dirPath}/${PackageName}.pfl;
export TEXLIVE_INSTALL_PREFIX=${InstallPrefix} &&
perl $${dirPath}/install-tl -profile $${dirPath}/${PackageName}.pfl;
break;
done
.PHONY: install