如何判断 makefile 是否正在从交互式 shell 运行?

发布于 2024-10-04 13:48:27 字数 307 浏览 4 评论 0原文

我有一个 makefile,它运行的命令可能需要一段时间。如果构建是从交互式 shell 启动的,我希望这些命令能够聊天,但如果不是(特别是通过 cron)启动,则更安静。类似于(伪代码)的内容:

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

all: bar baz
    foo $(foo_opts)

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

I have a makefile which runs commands that can take a while. I'd like those commands to be chatty if the build is initiated from an interactive shell but quieter if not (specifically, by cron). Something along the lines of (pseudocode):

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

all: bar baz
    foo $(foo_opts)

This is GNU make. If the specifics of what I'm doing matter, I can edit the question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

猥琐帝 2024-10-11 13:48:27

它并不严格确定它是否是从交互式 shell 调用的,但对于输出重定向到文件的 cron 作业,这个问题的答案与 如何检测我的 shell 脚本是否通过管道运行?:

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

编辑:要使用它在 Makefile 中设置变量(即在 GNU make 中):

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

ifdef INTERACTIVE
# is a terminal
else
# cron job
endif

It isn't strictly determining whether it is invoked from an interactive shell or not, but for a cron job in which the output is redirected to a file, the answer to this question would be the same as for How to detect if my shell script is running through a pipe?:

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

Edit: To use this to set a variable in a Makefile (in GNU make, that is):

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

ifdef INTERACTIVE
# is a terminal
else
# cron job
endif
流心雨 2024-10-11 13:48:27

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

5.5) 如何判断我是否正在运行交互式 shell?

  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

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

5.5) How can I tell if I am running an interactive shell?

  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
杀手六號 2024-10-11 13:48:27

我不认为你能轻易找到答案。我建议采用替代策略,可能是通过消除 cron 作业的详细输出。我希望使用这样的 makefile 来做到这一点:

VERBOSE = --verbose

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

all: bar baz
    foo $(foo_opts)

然后,在 cron 作业中,指定:

make VERBOSE=

VERBOSE 的这一命令行规范将覆盖 makefile 中的规范(并且不能由 makefile 更改)。这样,您设置一次并使用多次的专门任务(cron 作业)将在没有详细输出的情况下完成;构建的一般任务将详细完成(除非您选择覆盖命令行上的详细程度)。

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

I do not think you can easily find out. I suggest adopting an alternative strategy, probably by quelling the verbose output from the cron job. I would look to do that using a makefile like this:

VERBOSE = --verbose

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

all: bar baz
    foo $(foo_opts)

Then, in the cron job, specify:

make VERBOSE=

This command-line specification of VERBOSE overrides the one in the makefile (and cannot be changed by the makefile). That way, the specialized task (cron job) that you set up once and use many times will be done without the verbose output; the general task of building will be done verbosely (unless you elect to override the verbose-ness on the command line).

One minor advantage of this technique is that it will work with any variant of make; it does not depend on any GNU Make facility.

爱本泡沫多脆弱 2024-10-11 13:48:27

我不太确定“互动”是什么意思。您的意思是您是否有有效的 /dev/tty ?如果是这样,那么你可以检查一下。不过,我们大多数人都会在标准输入上检查 istty,因为它回答了我们想知道的问题:是否有人在打字。

I’m not really sure what "am interactive" means. Do you mean if you have a valid /dev/tty? If so, then you could check that. Most of us check isatty on stdin, though, because it answers the questions we want to know: is there someone there to type something.

日久见人心 2024-10-11 13:48:27

请注意:您还可以查看相关讨论< /a> 我有关于从 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 1 ] 替换为 [ -t 0 ] > 在我上面的代码中应该按原样工作。

希望这有帮助。

Just a note: you can also see the related discussion that I had about detecting redirection of STDOUT from inside a Makefile.

I believe it will be helpful to readers of this question - executive summary:

-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

In my answer there I explain why the [-t 1] has to be done in an action and not in a variable assignment (as in the recommended answer here), as well as the various pitfalls regarding re-evaluation of a generated Makefile (i.e. the piped.mk above).

The term interactive in this question seems to imply redirection of STDIN... in which case replacing [ -t 1 ] with [ -t 0 ] in my code above should work as-is.

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文