Why does this fragment of shell script give an error in a Makefile?
-@for file in `cat export_mojave_tcl_files.list`; do \
if { [ -f $(TEST_PATH)/$$file ] && [-f $$file]} ; \
then diff $$file bk_marker > $$file.diff ; \
if {! [ -s $$file.diff ]}; \
then rm -f $$file.diff ; \
else echo $$file >> marker.fill.tcl.diff; \
fi \
elif {[ -f $(TEST_PATH)/$$file] && ! [ -f $$file]} ; \
then echo $$file >> gold_exists; \
else echo $$file >> test_exists; \
fi; \
done ;
Error
/bin/sh: -c: line 1: syntax error near unexpected token `then'
/bin/sh: -c: line 1: `for file in `cat export_mojave_tcl_files.list`; do if { [ -f ../GOLD/$file ] && [-f $file] } ; then diff $file bk_marker > $file.diff ; if ! [ -s $file.diff ]}; then rm -f $file.diff ; else echo $file >> marker.fill.tcl.diff; fi elif { [ -f ../GOLD/$file] && ! [ -f $file] } ; then echo $file >> gold_exists; else echo $file >> test_exists; fi; done ;'
You need to be careful with spaces around the braces, and semi-colons before close braces..
In an orthodox shell derived from the Bourne shell (where
bashshares the same views on the subject), you need to write:The semi-colons before the close brace are necessary for the shell to recognize the close brace as the end of an I/O redirection unit. Of course, since there is no I/O redirection, it is all somewhat hypothetical. I believe you’d get the same effect from:
with no braces at all. I’ve seen worse abuses, such as:
This runs the tests in sub-shells, for no good reason. And, even worse, I’ve seen:
Fortunately, the test command does produce any output so the back-ticks don’t have anything to execute, but it is an appalling waste of processes.