我已经检查了关于SO的几篇文章,但无法获得我想要的答案。
我想将Stata脚本作为Makefile的一部分运行。因此,在我的目标之一中,我定义了
live_data:
@echo "Executing Stata code"
StataIC -e 'stata_code.do'
@exit_status=$?
@echo "Finished execution of Stata code."
@echo Code finished with exit code of $(exit_status)
但是,每当我查看make all
命令(包括live_data
)的输出时,都会看到
Executing Stata code
StataIC -e stata_code.do'
Finished execution of Stata code.
Code finished with exit code of
基本上,变量exit_code
始终为空。
但是,如果我弹出一个终端并简单地运行StataIC -e stata_code.do
,然后运行exit_status=$?
和echo $exit_status
,则会得到正确的结果(0或1)。有人可以指出我在这里到底想念什么吗?
您有几个问题。首先,正如@AProgrammer所指出的,配方中的每一行都是在其自己的子shell中执行的,因此,一行中设置的变量无法保存到下一行:
trial:
@var=blue
@echo this command has no access to what was stored in var
解决方案是将命令放在一行中
trial:
@var=blue ; echo this command can use what was stored in var
如果太长,请用反斜杠换行:
trial:
@var=blue ;\
echo this command can use what was stored in var
((请注意,只有一个制表符,即@
之前的一个;“ echo”左侧的空白只是一些使规则易于阅读的空格。]
第二,您必须注意语法。在Make中扩展变量的方法是$(var)
,而在shell中扩展变量的方法是$var
;在其他上下文中使用任何一种语法都不会给您想要的结果。
var=red
$(info $(var)) # this is a Make command
trial:
@var=blue ; echo this is a shell command, so $(var) will not work
第三,尽管规则中的命令是shell命令,但Make会尝试扩展运行规则后看到的任何变量[[之前,因此我们必须用另一个'$转义“ $ var”中的'$' ':
trial:
@var=blue ; echo $var will not work, but $$var will
将它们放在一起,我们得到:
live_data: @echo "Executing Stata code" ; \ StataIC -e 'stata_code.do' ; \ exit_status=$$? ; \ echo "Finished execution of Stata code." ; \ echo Code finished with exit code of $$exit_status
$?
的值。live_data:
@echo "Executing Stata code"; \
StataIC -e 'stata_code.do'; \
printf '%s\n' "Finished execution of Stata code." \
"Code finished with exit code of $$?"
[这里,两个字符串都是在printf
之后立即调用的单个StataIC
的参数,因此$?
正确地引用了StataIC
的退出状态。