home | list info | list archive | date index | thread index

Re: [OCLUG-Tech] how does one test if bash shell is interactive

  • Subject: Re: [OCLUG-Tech] how does one test if bash shell is interactive
  • From: Adrian Irving-Beer <wisq-oclug [ at ] wisq [ dot ] net>
  • Date: Tue, 9 Aug 2005 14:49:53 -0400
On Tue, Aug 09, 2005 at 01:54:46PM -0400, Ian! D. Allen wrote:

> Michael needs to clarify his question, given that "&" has nothing to do
> with a shell being interactive, nor does the use of "&" have anything
> to do with whether the shell that used it is itself an interactive shell.
> (Both interactive and non-interactive shells can start scripts using "&".)

Oops, missed this when I posted mine and said the same, sorry.

> If I ignore the question and concentrate on his wanting to test whether
> the script was started as "script &", we still need to know whether he
> wants exactly what he says (the script was *started* in the background,
> but may or may not be currently) or whether he wants to check the
> *current* foreground/background status of the script (which can change
> from second to second as you type ^Z and fg/bg at it).  Alas, I don't
> think there are easy answers to either question.

Actually, there's a really simple one, if you don't mind pausing for one
second:

	function no_term {
		# stuff to do if in background
	}
	trap no_term TTIN
	read -t 1 dummy
	# stuff to do if in foreground

When a script is launched with '&', attempting to read from the
controlling terminal sends a TTIN signal.  This normally stops the
process, but you can trap it instead.

With something like Perl or C, this could be made even faster, by
using ualarm() (in Time::HiRes for Perl).  In C:

	#include <stdlib.h>
	#include <unistd.h>
	#include <signal.h>

	void handler(int sig) {
		exit(1);
	}

	int main(void) {
		char buf[1];
		signal(SIGTTIN, &handler);
		read(0, &buf, 0);	
		exit(0);
	}

Then you can launch a nice little fast program and just check its error
status, with absolutely no wait time (unlike the all-bash solution).
This can be used initially to determine the launch status, or at any
point to determine if you're in the foreground.

Note that if the terminal isn't an interactive shell, it considers
that to be 'foreground' (no TTIN signal on read).  You'll want to also
check the 'test -t' value as per my previous message.

Attachment: signature.asc
Description: Digital signature