为什么shell会在Makefile中抱怨这个脚本?

时间:2011-07-12 14:01:39

标签: shell makefile

为什么这个shell脚本片段会在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 ;

错误

/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 ;'

1 个答案:

答案 0 :(得分:2)

你需要注意大括号周围的空格,以及紧密括号前的分号。

if { [ -f $(TEST_PATH)/$$file ] && [-f $$file]} ; \
                                              ^ here!
then diff $$file bk_marker > $$file.diff ; \
if {! [ -s $$file.diff ]}; \
    ^ here!             ^ here!

在源自Bourne shell的正统shell中(bash在主题上共享相同的视图),您需要写:

if { [ -f $(TEST_PATH)/$$file ] && [-f $$file] ; } ; \
then diff $$file bk_marker > $$file.diff ; \
if { ! [ -s $$file.diff ] ; }; \

关闭括号前的分号是shell必须将闭括号识别为I / O重定向单元的末尾。当然,由于没有I / O重定向,所以有点假设。我相信你会得到同样的效果:

if [ -f $(TEST_PATH)/$$file ] && [-f $$file] ; \
then diff $$file bk_marker > $$file.diff ; \
if ! [ -s $$file.diff ]; \

根本没有牙套。我看到了更糟糕的滥用行为,例如:

if ( [ -f $(TEST_PATH)/$$file ] && [-f $$file]) ; \
then diff $$file bk_marker > $$file.diff ; \
if (! [ -s $$file.diff ]); \

这在子shell中运行测试,没有充分的理由。而且,更糟糕的是,我看到了:

if ( `[ -f $(TEST_PATH)/$$file ] && [-f $$file]`) ; \
then diff $$file bk_marker > $$file.diff ; \
if (! `[ -s $$file.diff ]`); \

幸运的是,test命令确实产生了任何输出,因此反向标记没有任何要执行的东西,但这是一个令人震惊的进程浪费。