Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

How to know if a perl script is put in the background

by rapide (Beadle)
on Nov 18, 2008 at 16:08 UTC ( [id://724312]=perlquestion: print w/replies, xml ) Need Help??

rapide has asked for the wisdom of the Perl Monks concerning the following question:

I've tried to find an answer to this problem but It seems like there is something which I do not quite understand:

I have a script in which dumps a lot of output to the shell. When I do use the ampersand (&) to run the script as a background process it still prints the same output to the shell. So my questions is: Is it possible for the script to know that it has been put in the background by ampersand so that it can silence itself (re-direct STDOUT/STDERR TO /dev/null)?

Update: Thanks everyone for great feedback. I got what I was looking for and I ended up with a check that was in almuts link:

171 if (!open(TTY, "/dev/tty")) { 172 print "no tty\n"; 173 } else { 174 my $tpgrp = tcgetpgrp(fileno(*TTY)); 175 my $pgrp = getpgrp(); 176 if ($tpgrp == $pgrp) { 177 print "foreground\n"; 178 } else { 179 print "background\n"; 180 } 181 }

Replies are listed 'Best First'.
Re: How to know if a perl script is put in the background
by almut (Canon) on Nov 18, 2008 at 16:37 UTC
    Is Process Running In The Background?

    Update: BTW, I'm a bit surprised that your backgrounded script's stdout/stderr is going to the terminal. Normally, it wouldn't, if you start a script from the shell using & without redirecting those handles. The shell would stop the backgrounded script in case it's writing anything to stdout or stderr....   Could you provide some sample code that shows what you're doing / allows to reproduce the issue?  Which OS, which shell?

      BTW, I'm a bit surprised that your backgrounded script's stdout/stderr is going to the terminal. Normally, it wouldn't, if you start a script from the shell using & without redirecting those handles. The shell would stop the backgrounded script in case it's writing anything to stdout or stderr....
      It's my experience that backgrounded jobs still write STDERR to the screen/terminal under every shell/OS combination. For example,
      tar cvf /dev/null /usr/local &
      fills my OS X terminal, as it does on Solaris and OpenBSD.

        ... fills my OS X terminal, as it does on Solaris and OpenBSD.

        Not here... (Linux / bash with default settings) — But I suppose this discussion is getting off-topic with respect to the original question.

        Update: Here's the respective paragraph from bash's man page:

        JOB CONTROL
        (...) Only foreground processes are allowed to read from or write to the terminal. Background processes which attempt to read from (write to) the terminal are sent a SIGTTIN (SIGTTOU) signal by the terminal driver, which, unless caught, suspends the process.

      I created a small sample for you below. This behaves the same way ..
      OS: Linux 2.6.9-67.0.20 (SCL - Scientific Linux 4)
      Shell: bash
      Perl: 5.8.5
      1 #!/usr/bin/perl 2 3 use strict; 4 use warnings; 5 6 print "# Start script\n"; 7 print "\n -> Waiting 2 seconds\n"; 8 sleep(2); 9 print "\n -> Waiting 2 seconds\n"; 10 sleep(2); 11 print "# Exiting .. \n";

        Can't reproduce it, though I'm also using Linux and bash.  With your sample code I'm getting something like:

        $ ./724323.pl & [2] 10620

        (no further output)

        $ ps x | grep 724323 10620 pts/1 T 0:00 /usr/bin/perl ./724323.pl

        (the 'T' indicates that the script has been stopped)

        $ fg ./724323.pl # Start script -> Waiting 2 seconds -> Waiting 2 seconds # Exiting ..

        (after foregrounding it, output continues normally)

      Depends on your shell. I run things in the background all of the time (tail /this/logfile&^Jtail /that/logfile &). As long as input is not required, they run just fine.

      --MidLifeXis

Re: How to know if a perl script is put in the background
by moritz (Cardinal) on Nov 18, 2008 at 16:16 UTC
    I haven't tried it right now, but you might be able to use the -t operator to test if STDIN is connected to a terminal, it might return false for a backgrounded job.
      Way to go moritz - same conclusion/assumption here, but you're obviously a quicker typist :-)

      A user level that continues to overstate my experience :-))
Re: How to know if a perl script is put in the background
by lostjimmy (Chaplain) on Nov 18, 2008 at 16:44 UTC
    Why not just redirect the output yourself? # ./script.pl > /dev/null 2>&1
      Normally I would do that, but I'm creating scripts that is used by non-technical personnel.
      Their ability to find the '>' sign on the keyboard is limited :-)
        But typing shift-7 is so much harder than shift-. :) In the interest of simplicity, why don't you provide wrapper shell for the background:
        #! /bin/bash realProgram $* &> /dev/null &
        Then they don't have to mess with any of those pesky non-alphanumerics at all :)
Re: How to know if a perl script is put in the background
by mifflin (Curate) on Nov 18, 2008 at 20:56 UTC
    I think I read in "Perl Best Practices" that using -t is not always accurate. The author (Damian Conway) suggests using something like this...

    use IO::Interactive qw(is_interactive); if ( is_interactive() ) { print "Running interactively\n"; }

      Looking at the implementation of IO::Interactive, it's essentially -t plus some code to handle *ARGV magicness. In other words, it shares the same problem of possibly producing incorrect results when being (mis)used to test if something is running in the background (e.g. when a script is sent into the background using &, executed from an (interactive) command line):

      $ ./724312.pl Running interactively $ stty -tostop # just in case $ ./724312.pl & [1] 13831 $ Running interactively [1]+ Done ./724312.pl
Re: How to know if a perl script is put in the background
by DrHyde (Prior) on Nov 19, 2008 at 11:06 UTC
    Don't forget to handle the edge case where a process can move back and forth between the foreground and background. eg, start your process in the foreground, press C-z to stop it, type 'bg' to background it, type 'fg' to foreground it again, and so on.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://724312]
Approved by planetscape
Front-paged by almut
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2024-03-28 21:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found