I got an error message:
-d was unexpected at this time
while running the following (see line 3: if [-d ".git"])
autoversion:
#( \
if [ -d ".git" ] && which git > /dev/null ; then \
DETECTED_VERSION=$$(git describe --always --tags --dirty) ; \
else \
DETECTED_VERSION=$$(grep -v "^#" "$(RELEASED_VERSION_FILE)") ; \
if basename $$(pwd) | grep -q "^[[:alnum:]]*-bedtools-[[:alnum:]]*$$" ; then \
DETECTED_VERSION=$${DETECTED_VERSION}-zip-$$(basename "$$(pwd)" | sed 's/^[[:alnum:]]*-bedtools-//') ; \
fi ; \
fi ; \
\
CURRENT_VERSION="" ; \
[ -e "$(VERSION_FILE)" ] && CURRENT_VERSION=$$(grep "define VERSION_GIT " "$(VERSION_FILE)" | cut -f3 -d" " | sed 's/"//g') ; \
\
echo "DETECTED_VERSION = $$DETECTED_VERSION" ; \
echo "CURRENT_VERSION = $$CURRENT_VERSION" ; \
if [ "$${DETECTED_VERSION}" != "$${CURRENT_VERSION}" ] ; then \
echo "Updating version file." ; \
echo "#ifndef VERSION_GIT_H" > $(VERSION_FILE) ; \
echo "#define VERSION_GIT_H" >> $(VERSION_FILE) ; \
echo "#define VERSION_GIT \"$${DETECTED_VERSION}\"" >> $(VERSION_FILE) ; \
echo "#endif /* VERSION_GIT_H */" >> $(VERSION_FILE) ; \
fi )
What is the problem?
Related
I have a make target, which i usually need to run twice to get accurate outcome. I.e the 1st run if accurate thenn on the 2nd run, if the variable is changed, it still displays the previous output, which is wrong, is there a way to get rid of cache or clear it in between.
.PHONY:check-tf-lint
check-tf-lint: configure ## TF Linting
$(eval list_of_dir := $(shell cd ${deployment} && ls -ld */ | awk '{print $$NF}'| grep -v 'test_cases'| sed 's|/||g'))
$(shell touch ${quality-metrics}/formatting.txt)
#for i in aws_bot; do \
make set-tf-version -e infra_module_path=$$i; \
terraform fmt -check -list=false ${deployment}/$$i ; \
if [ "$$?" != "0" ]; then \
echo "Need Formatting in $$i" >> ${quality-metrics}/formatting.txt; \
terraform fmt -check ${deployment}/$$i >> ${quality-metrics}/formatting.txt; \
echo "" >> ${quality-metrics}/formatting.txt; \
fi \
done
$(eval TMP := $(shell (cat ${quality-metrics}/formatting.txt | wc -l)))
echo "${TMP}"
#if [ "$(TMP)" = "0" ]; then \
echo "All Good! No Formatting Needed."; \
else \
echo "Kindly Format Below Mentioned code and check in Again"; \
cat ${quality-metrics}/formatting.txt; \
fi
$(shell rm -rf ${quality-metrics}/formatting.txt)
#if [ "$(TMP)" != "0" ]; then \
exit 1; \
fi
Rule of thumb: you should never use eval or shell functions in a make recipe. If you are doing that it's a pretty sure sign that something has gone wrong somewhere.
In your case the reason you see this behavior is that make will expand ALL variables and functions for all lines in a recipe before the first line in the recipe is invoked. So as far as make is concerned your recipe is handled like this:
.PHONY:check-tf-lint
check-tf-lint: configure ## TF Linting
$(eval list_of_dir := $(shell cd ${deployment} && ls -ld */ | awk '{print $$NF}'| grep -v 'test_cases'| sed 's|/||g'))
$(shell touch ${quality-metrics}/formatting.txt)
$(eval TMP := $(shell (cat ${quality-metrics}/formatting.txt | wc -l)))
$(shell rm -rf ${quality-metrics}/formatting.txt)
#for i in aws_bot; do \
make set-tf-version -e infra_module_path=$$i; \
terraform fmt -check -list=false ${deployment}/$$i ; \
if [ "$$?" != "0" ]; then \
echo "Need Formatting in $$i" >> ${quality-metrics}/formatting.txt; \
terraform fmt -check ${deployment}/$$i >> ${quality-metrics}/formatting.txt; \
echo "" >> ${quality-metrics}/formatting.txt; \
fi \
done
echo "${TMP}"
#if [ "$(TMP)" = "0" ]; then \
echo "All Good! No Formatting Needed."; \
else \
echo "Kindly Format Below Mentioned code and check in Again"; \
cat ${quality-metrics}/formatting.txt; \
fi
#if [ "$(TMP)" != "0" ]; then \
exit 1; \
fi
You should always write your recipes using shell facilities and not make facilities. Set shell variables, don't use eval to set make variables, and run shell commands directly (you're in a recipe after all!) rather than using make's shell function.
You may need to put all the lines in a single script (with semicolon / backslash) to allow this to work. Or consider .ONESHELL but that's a much bigger set of changes.
This worked for me !
.PHONY:check-tf-lint
check-tf-lint: ## TF Linting
$(eval list_of_dir := $(shell cd ${deployment} && ls -ld */ | awk '{print $$NF}'| grep -v 'test_cases'| sed 's|/||g'))
#for i in $(list_of_dir); do \
make set-tf-version -e infra_module_path=$$i; \
terraform fmt -check -list=false ${deployment}/$$i ; \
if [ "$$?" != "0" ]; then \
echo "Need Formatting in $$i" >> ${quality-metrics}/formatting.txt; \
terraform fmt -check ${deployment}/$$i >> ${quality-metrics}/formatting.txt; \
echo "" >> ${quality-metrics}/formatting.txt; \
fi \
done
#if [ -e "${quality-metrics}/formatting.txt" ]; then \
export MNC=`cat ${quality-metrics}/formatting.txt | wc -l`; \
if [ "$${MNC}" = "0" ]; then \
echo "All Good! No Formatting Needed."; \
else \
echo ""; \
echo "Kindly Format Below Mentioned code and check in Again"; \
cat ${quality-metrics}/formatting.txt; \
fi; \
rm -rf ${quality-metrics}/formatting.txt; \
if [ "$${MNC}" != "0" ]; then \
exit 1; \
fi \
fi
I got this script which reads a delimited part of my .gitignore file and remove all files after the given mark # #:
# https://stackoverflow.com/questions/55527923/how-to-stop-makefile-from-expanding-my-shell-output
RAW_GITIGNORE_CONTENTS := $(shell while read -r line; do printf "$$line "; done < ".gitignore")
GITIGNORE_CONTENTS := $(shell echo "$(RAW_GITIGNORE_CONTENTS)" | sed -E $$'s/[^\#]+\# //g')
# https://stackoverflow.com/questions/4210042/exclude-directory-from-find-command
DIRECTORIES_TO_CLEAN := $(shell /bin/find -not -path "./**.git**" -not -path "./pictures**" -type d)
clean:
# https://stackoverflow.com/questions/10586153/split-string-into-an-array-in-bash
# https://stackoverflow.com/questions/11289551/argument-list-too-long-error-for-rm-cp-mv-commands
readarray -td' ' GARBAGE_DIRECTORIES <<<"$(DIRECTORIES_TO_CLEAN) "; \
unset 'GARBAGE_DIRECTORIES[-1]'; \
declare -p GARBAGE_DIRECTORIES; \
readarray -td' ' GARBAGE_EXTENSIONS <<<"$(GITIGNORE_CONTENTS) "; \
unset 'GARBAGE_EXTENSIONS[-1]'; \
declare -p GARBAGE_EXTENSIONS; \
for filename in "$${GARBAGE_DIRECTORIES[#]}"; \
do \
arraylength="$${#GARBAGE_EXTENSIONS[#]}"; \
printf 'Cleaning %s extensions on %s\n' "$${arraylength}" "$$filename"; \
for extension in "$${GARBAGE_EXTENSIONS[#]}"; \
do \
[[ ! -z "$$filename" ]] || continue; \
[[ ! -z "$$extension" ]] || continue; \
full_expression="$${filename}/$${extension}" ;\
printf '%s\n' "$$full_expression"; \
rm -v "$$full_expression"; \
done; \
done;
Running it with the following .gitignore file:
*.txt
*.var
# Comment #
*.aux
The rm command is not expanding the wildcards and keeps telling me rm: cannot remove './*.aux': No such file or directory and do not remove the *.aux files from the ./ directory.
Update
After asked on a comment by #Beta, I simplified the Makefile to this:
GITIGNORE_CONTENTS := "*.aux" "*.lof"
DIRECTORIES_TO_CLEAN := "./setup/cache" "./setup/cache/chapters"
clean:
readarray -td' ' GARBAGE_DIRECTORIES <<<"$(DIRECTORIES_TO_CLEAN) "; \
unset 'GARBAGE_DIRECTORIES[-1]'; \
declare -p GARBAGE_DIRECTORIES; \
readarray -td' ' GARBAGE_EXTENSIONS <<<"$(GITIGNORE_CONTENTS) "; \
unset 'GARBAGE_EXTENSIONS[-1]'; \
declare -p GARBAGE_EXTENSIONS; \
for filename in "$${GARBAGE_DIRECTORIES[#]}"; \
do \
arraylength="$${#GARBAGE_EXTENSIONS[#]}"; \
printf 'Cleaning %s extensions on %s\n' "$${arraylength}" "$$filename"; \
for extension in "$${GARBAGE_EXTENSIONS[#]}"; \
do \
[[ ! -z "$$filename" ]] || continue; \
[[ ! -z "$$extension" ]] || continue; \
full_expression="$${filename}/$${extension}" ;\
printf '%s\n' "$$full_expression"; \
rm -vf "$$full_expression"; \
done; \
done;
Which results on this output after running it:
$ make
readarray -td' ' GARBAGE_DIRECTORIES <<<""./setup/cache" "./setup/cache/chapters" "; \
unset 'GARBAGE_DIRECTORIES[-1]'; \
declare -p GARBAGE_DIRECTORIES; \
readarray -td' ' GARBAGE_EXTENSIONS <<<""*.aux" "*.lof" "; \
unset 'GARBAGE_EXTENSIONS[-1]'; \
declare -p GARBAGE_EXTENSIONS; \
for filename in "${GARBAGE_DIRECTORIES[#]}"; \
do \
arraylength="${#GARBAGE_EXTENSIONS[#]}"; \
printf 'Cleaning %s extensions on %s\n' "${arraylength}" "$filename"; \
for extension in "${GARBAGE_EXTENSIONS[#]}"; \
do \
[[ ! -z "$filename" ]] || continue; \
[[ ! -z "$extension" ]] || continue; \
full_expression="${filename}/${extension}" ;\
printf '%s\n' "$full_expression"; \
rm -vf "$full_expression"; \
done; \
done;
declare -a GARBAGE_DIRECTORIES=([0]="./setup/cache" [1]="./setup/cache/chapters")
declare -a GARBAGE_EXTENSIONS=([0]="*.aux" [1]="*.lof")
Cleaning 2 extensions on ./setup/cache
./setup/cache/*.aux
./setup/cache/*.lof
Cleaning 2 extensions on ./setup/cache/chapters
./setup/cache/chapters/*.aux
./setup/cache/chapters/*.lof
More simplification
I reduced to the more simple version it could be:
clean:
rm -v "./setup/cache/*.aux";
Running this, also do not remove the files:
$ make
rm -v "./setup/cache/*.aux";
rm: cannot remove './setup/cache/*.aux': No such file or directory
make: *** [Makefile:3: clean] Error 1
$ ls ./setup/cache/*.aux
./setup/cache/main.aux
On above, after running ls, you can see the file still exists and it is there.
I managed to fix it by changing:
rm -vf "$$full_expression"; \
To:
rm -vf $${full_expression}; \
In the code below I am attempting to assign variables to the two yad values Radius and Amount.
This can be done with awk by printing the yad values to file but I want to avoid this if I can.
The string (that is, both yad values) is assigned a variable and trimmed of characters, as required, using sed. However, the script stops at this line;
radius=$(sed 's|[amount*,]||g')
Two questions
is there a better way of tackling this; and
why is the script not completing? I have not been able to figure out the syntax.
EDIT: don't need the loop and working on the sed syntax
#!/bin/bash
#ifs.sh
values=`yad --form --center --width=300 --title="Test" --separator=' ' \
--button=Skip:1 \
--button=Apply:0 \
--field="Radius":NUM \
'0!0..30!1!0' \
--field="Amount":NUM \
'0!0..5!0.01!2'`
radius=$(echo "$values" | sed 's|[amount*,]||g')
amount=$(echo "$values" | sed 's/.a://')
if [ $? = 1 ]; then
echo " " >/dev/null 2>&1; else
echo "Radius = $radius"
echo "Amount = $amount"
fi
exit
Alternatives
# with separator
# radius="${values%????????}"
# amount="${values#????????}"
# without separator
# radius=$(echo "$values" | sed s'/........$//')
# amount=$(echo "$values" | sed 's/^........//')
It's easier than you think:
$ values=( $(echo '7.000000 0.100000 ') )
$ echo "${values[0]}"
7.000000
$ echo "${values[1]}"
0.100000
Replace $(echo '7.000000 0.100000 ') with yad ... so the script would be:
values=( $(yad --form --center --width=300 --title="Test" --separator=' ' \
--button=Skip:1 \
--button=Apply:0 \
--field="Radius":NUM \
'0!0..30!1!0' \
--field="Amount":NUM \
'0!0..5!0.01!2') )
if [ $? -eq 0 ]; then
echo "Radius = ${values[0]}"
echo "Amount = ${values[1]}"
fi
EDIT: Changed answer based on #Ed Morton
#!/bin/bash
#ifs.sh
values=($(yad --form --center --width=300 --title="Test" --separator=' ' \
--button=Skip:1 \
--button=Apply:0 \
--field="Radius":NUM \
'0!0..30!1!0' \
--field="Amount":NUM \
'0!0..5!0.01!2'))
if [ $? -eq 0 ]; then
radius="${values[0]}"
amount="${values[1]}"
fi
exit
bash -x Output
+ '[' 0 -eq 0 ']'
+ radius=7.000000
+ amount=1.000000
+ exit
HOMEDIR = $(shell pwd)
DEFAULT = 4.0.3
YESDIR = $(shell echo $(#:install-%=%) | tr A-Z a-z)
NODIR = $(shell echo $(#:clean-%=%) | tr A-Z a-z)
install:
#$(MAKE) install-$(DEFAULT)
install-%:
#cd $(HOMEDIR);\
if [ ! -e $(YESDIR) ]; then \
echo "Library $(#:install-%=%) Version=$(YESDIR) does not exist"; \
elif [ -e $(YESDIR)/Install.sh ]; then \
echo "Installing $(PKGNAM) version=$(YESDIR)" ; \
cd $(YESDIR) ;\
$(SHELL) Install.sh $(HOMEDIR) 1 ;\
elif [ -e $(YESDIR)/Makefile ]; then \
cd $(YESDIR); \
$(MAKE); \
else \
echo "Installation instruction for $(#:install-%=%) Version=$(YESDIR) does not exist"; \
fi;
the above makefile gives me the following error
line 6: syntax error: unexpected end of file
Remove trailing blanks in this line:
$(SHELL) Install.sh $(HOMEDIR) 1 ;\
I am trying to write a target in a makefile which will read a variable(having IPs) from one of the .mk file and if a space separated list found split it and take some action.
Issue i am facing that the string do not split and in for loop do not get the value either.
Have tried following
GWTS_FE_IPS=2600:40f0:3e::2 2600:40f0:3e::3 2600:40f0:3e::4 2600:40f0:3e::5
test:
$(eval IPS=$(shell echo "$(GW_IPS)" |awk -F " " '{print NF}'))
if [ ${IPS} -gt 1 ]; then \
echo "Multiple Ips [$(GW_IPS)]"; \
for ip in $(shell echo "${GW_IPS}" | sed -e 's/ /\n/g'); \
do \
echo ".... $(ip) ...."; \
done \
else \
echo "Single IP [$(GW_IPS)]"; \
fi
Result i get is
2600:40f0:3e::2n2600:40f0:3e::3n2600:40f0:3e::4n2600:40f0:3e::5
if [ 4 -gt 1 ]; then \
echo "Multiple Ips [2600:40f0:3e::2 2600:40f0:3e::3 2600:40f0:3e::4 2600:40f0:3e::5]"; \
for ip in 2600:40f0:3e::2n2600:40f0:3e::3n2600:40f0:3e::4n2600:40f0:3e::5; \
do \
echo ".... ...."; \
done \
else \
echo "Single IP [2600:40f0:3e::2 2600:40f0:3e::3 2600:40f0:3e::4 2600:40f0:3e::5]"; \
fi
Multiple Ips [2600:40f0:3e::2 2600:40f0:3e::3 2600:40f0:3e::4 2600:40f0:3e::5]
.... ....
Can any one give some pointers.
You are trying to do too many things at once without testing any of them. When you try new tools, try them one at a time.
GWTS_FE_IPS=2600:40f0:3e::2 2600:40f0:3e::3 2600:40f0:3e::4 2600:40f0:3e::5
IPS := $(words $(GWTS_FE_IPS))
test:
#if [ ${IPS} -gt 1 ]; then \
echo "Multiple Ips [$(GW_IPS)]"; \
for ip in $(GWTS_FE_IPS) ; \
do \
echo ".... $$ip ...."; \
done \
else \
echo "Single IP [$(GW_IPS)]"; \
fi