2010-11-23 132 views
5

我有一个makefile,它运行需要一段时间的命令。如果构建是从交互式shell启动的,但是不安静(特别是通过cron),那么我会希望这些命令很健谈。 (伪代码):如何判断makefile是否从交互式shell运行?

foo_opts = -a -b -c 
if (make was invoked from an interactive shell): 
    foo_opts += --verbose 

all: bar baz 
    foo $(foo_opts) 

这是GNU make。如果我所做的事情的细节很重要,我可以编辑这个问题。

回答

5

它不是严格地确定它是否从交互式shell中调用,但对于将输出重定向到文件的cron作业,此问题的答案与How to detect if my shell script is running through a pipe?的相同:

if [ -t 0 ] 
then 
    # input is from a terminal 
fi 

编辑:要使用此设置一个变量在一个Makefile(在GNU做,这是):

INTERACTIVE:=$(shell [ -t 0 ] && echo 1) 

ifdef INTERACTIVE 
# is a terminal 
else 
# cron job 
endif 
4

http://www.faqs.org/faqs/unix-faq/faq/part5/section-5.html

5.5)我怎样才能知道我是否正在运行一个交互式的壳呢?

In the C shell category, look for the variable $prompt. 

    In the Bourne shell category, you can look for the variable $PS1, 
    however, it is better to check the variable $-. If $- contains 
    an 'i', the shell is interactive. Test like so: 

     case $- in 
     *i*) # do things for interactive shell 
       ;; 
     *)  # do things for non-interactive shell 
       ;; 
     esac 
+1

对不起,你的游行队伍下雨了,但是它告诉你你运行的shell是否是交互式运行的,但是在makefile里面,你运行的任何shell都会声称它是非交互式运行的,即使`make`是本身从交互式shell运行。证明:`makefile`包含``all:; echo“Shell:$$ - ”`“并运行'make',它不会在输出中包含'i'。 (在我的Mac上,从我的交互式shell中,'make'与'himBH'相比'hBc')。 – 2010-11-23 00:25:16

+0

嗯..也许OP可以检查shell中调用make并设置环境变量在makefile中捕获。 – Naveen 2010-11-23 00:33:14

+0

环境变量排序 - 大多可用,但不是很令人满意。 – 2010-11-23 01:13:13

4

我不认为你可以轻易找出答案。我建议采用另一种策略,可能是通过压缩cron作业的详细输出。我是这样看,使用这样的生成文件做:

VERBOSE = --verbose 

foo_opts = -a -b -c ${VERBOSE} 

all: bar baz 
    foo $(foo_opts) 

然后,在cron作业,指定:

make VERBOSE= 

此详细的命令行规范覆盖了一个在生成文件(和不能被makefile改变)。这样,您设置并使用多次的专用任务(cron job)将在没有详细输出的情况下完成;构建的一般任务将会被详细地完成(除非您选择覆盖命令行上的详细内容)。

这种技术的一个小优点是它可以与make的任何变体一起使用;它不依赖任何GNU Make工具。

0

我真的不知道什么是“我互动”的意思。你是说如果你有一个有效的/dev/tty?如果是这样,那么你可以检查。但是,我们大多数人在stdin上检查isatty,因为它回答了我们想知道的问题:是否有人在那里键入内容。

0

请注意:您还可以看到the related discussion,我有关于检测从Makefile中重定向STDOUT的信息。

我相信这将有助于这个问题的读者 - 执行摘要:

-include piped.mk 

all: piped.mk 
ifeq ($(PIPED),1) 
    @echo Output of make is piped because PIPED is ${PIPED} 
else 
    @echo Output of make is NOT piped because PIPED is ${PIPED} 
endif 
    @rm -f piped.mk 

piped.mk: 
    @[ -t 1 ] && PIPED=0 || PIPED=1 ; echo "PIPED=$${PIPED}" > piped.mk 

$ make 
Output of make is NOT piped because PIPED is 0 

$ make | more 
Output of make is piped because PIPED is 1 

在我的答案在那里我解释为什么[-t 1]有一个动作,而不是在一个变量赋值来完成(如在这里推荐的答案),以及关于重新评估生成的Makefile(即上面的piped.mk)的各种陷阱。

该术语互动在这个问题似乎暗示重定向STDIN ...在这种情况下,在上面的代码中用[ -t 0 ]代替[ -t 1 ]应该按原样工作。

希望这会有所帮助。

相关问题