Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I tell if a makefile is being run from an interactive shell?

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.

like image 655
Reid Avatar asked Nov 23 '10 00:11

Reid


People also ask

How do you know if a shell is interactive?

If a script needs to test whether it is running in an interactive shell, it is simply a matter of finding whether the prompt variable, $PS1 is set. (If the user is being prompted for input, then the script needs to display a prompt.) Alternatively, the script can test for the presence of option "i" in the $- flag.

What shell does Makefile use?

By default make uses the /bin/sh shell. The default can be over ridden by using the variable SHELL = /bin/sh or equivalent to use the shell of your preference. This variable should be included in every descriptor file to make sure the same shell is used each time the descriptor file is executed.

How do I know if bash is interactive?

A bash shell is considered as an interactive shell when it reads and writes data from a user's terminal. Most startup scripts examine the shell variable called PS1. Usually, PS1 is set in interactive shells, and it is unset in non-interactive shells.

What is the interactive shell in terminal?

An interactive shell is one started without non-option arguments, unless -s is specified, without specifying the -c option, and whose input and error output are both connected to terminals (as determined by isatty(3) ), or one started with the -i option.


3 Answers

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
like image 111
PleaseStand Avatar answered Oct 24 '22 08:10

PleaseStand


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
like image 41
Naveen Avatar answered Oct 24 '22 08:10

Naveen


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.

like image 24
Jonathan Leffler Avatar answered Oct 24 '22 08:10

Jonathan Leffler