2014-05-24 24 views
3

我想在shell中运行某些操作,具体取决于当前目录中的默认生成文件是否包含特定目标。如何在生成文件中检查目标的存在

#!/bin/sh 
make -q some_target 
if test $? -le 1 ; then 
    true # do something 
else 
    false # do something else  
fi 

这是有效的,因为如果目标不存在,GNU make返回错误代码2,否则返回0或1。问题是没有以这种方式记录。这里是男人的一部分:

-q, --question 
     ``Question mode''. Do not run any commands, or print anything; 
     just return an exit status that is zero if the specified targets 
     are already up to date, nonzero otherwise. 

只有零/非零区分。什么是正确的方法来做到这一点?

回答

2

您应该阅读the GNU make manual而不是手册页:手册页仅仅是一个摘要而非完整的定义。该手册说:

The exit status of make is always one of three values: 

0 The exit status is zero if make is successful 

2 The exit status is two if make encounters any errors. It will print messages 
    describing the particular errors. 

1 The exit status is one if you use the ‘-q’ flag and make determines that 
    some target is not already up to date. 

由于试图创建一个不存在的目标是一个错误,你总是会在这种情况下得到一个退出码2。

+0

所以没有办法从其它任何区分这种错误,而是通过解析stderr输出? – sshilovsky

+0

正确; make不会为可能遇到错误的每种可能方式使用不同的错误代码。 – MadScientist

2

迟到的答案,但也许它会帮助人们在未来面临同样的问题。

我使用下面的方法,它需要您修改Makefile(您需要添加一个%-rule-exists模式规则)。如果你不想这样做,你可以直接从你的脚本运行make -n your-target-to-check &> /dev/null

我使用它来获得autobuild和autoupload等命令,这些命令包含在代码片段中的上下文中。

%-rule-exists: 
    @$(MAKE) -n $* &> /dev/null 


auto%: %-rule-exists 
    $(info Press CTRL-C to stop $*ing) 
    @while inotifywait -qq -r -e move -e create -e modify -e delete --exclude "\.#.*" src; do make $* ||: ; date ; done 

输出示例:

$ make build-rule-exists; echo Exit code: $? 
Exit code: 0 
$ make nonsense-rule-exists; echo Exit code: $? 
Exit code: 2 

注意,它实际上并没有建立目标,以找出是否该规则存在的make-n标志的礼貌。即使构建失败,我也需要它来工作。

2

另一种可能性是,从读入makefile导致数据库中的grep:

some_target:   
    @ if $(MAKE) -C subdir -npq --no-print-directory .DEFAULT 2>/dev/null | grep -q "^[email protected]:" ; \ 
    then                     \ 
       echo "do something" ;               \ 
    fi 

其中

-n --just-print, --dry-run 
    Print the commands that would be executed, but do not execute them. 

-p, --print-data-base 
    Print the data base (rules and variable values) that results from reading 
    the makefiles 

-q, --question 
    Question mode. Do not run any commands, or print anything; just return and 
    exit status that is zero if the specified targets are already up to date, 
    nonzero otherwise. 
相关问题