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

Hello monks,

I'm working in an error report script that must send a mail to a mail group when any of the scripts associated to it fail. It's currently working, but I would like to add the script name that failed as the subject of the mail. The script is called with a system() call.

Is there any way to know the name of the caller process? (I'm working in an UNIX evironment) I've thought in passing name as a param, but this would mean change about 30 different scripts 8(.

Thanks in advance,
deibyz

Replies are listed 'Best First'.
Re: Parent process name
by Abigail-II (Bishop) on May 28, 2004 at 13:43 UTC
    On Linux and other Unix systems with a similar /proc filesystem:
    my ($name) = `cat /proc/@{[getppid]}/cmdline` =~ /^(\S+)/
    (This assumes you don't have sneaky program names with spaces in them).

    Abigail

Re: Parent process name
by gsiems (Deacon) on May 28, 2004 at 13:48 UTC
    You mean something along the lines of:
    #!/usr/bin/perl use strict; use warnings; my $parent_id; foreach (`ps -ef`) { my ($uid,$pid,$ppid) = split; next unless ($pid eq $$); $parent_id = $ppid; last; } my $parent = (grep {/^\s*\d+/} (`ps -p $parent_id`))[0]; my $parent_name = (split /\s+/, $parent, 5)[4]; print $parent_name;
    On my Linux box it outputs the following:
      $ ./parent-process.pl
      bash
      $
    
      Thanks a lot!

      It works with one little change:

      $ ps -p xxxx PID TTY TIME CMD 29580 pts/4 00:00:00 bash $ ps -p yyyy PID TTY TIME CMD 9556 pts/49 0:00 bash
      See the blank space? Depending on it presence, I have to take the forth or the fifth elemnt of the last split. It works changing this line:
      my $parent = (grep {/^\s*\d+/} (`ps -p $parent_id`))[0];
      With this:
      my $parent = " ".(grep {/^\s*\d+/} (`ps -p $parent_id`))[0];
      Now I have at least one blank and have allways to take fifth element. Thanks again for the code.
      BTW, even if I work with UNIX, I must deal with different flavours (UNIX, Solaris, HP-UX...) and don't know if ps will output the same format everywhere (I'm going to test it).

      And the worst thing, I've just been told to make it run on Window$ 8( Is there anyway to get rid of the ps calls?

        Good catch on the leading space ++

        "And the worst thing, I've just been told to make it run on Window$" Ouch!

        Well there's Win32::Process::Info for MS (which I have not used and know nothing about) and Proc::ProcessTable for unix (which I haven't used yet either), but they might be worth looking at.

        Here's a windows version:

        use strict; use Win32::Process::Info; my $pihandle = Win32::Process::Info->new(); my @procinfo = $pihandle->GetProcInfo(); my $ParentPID; my %ProcNames; foreach my $PIDInfo (@procinfo) { $ProcNames{$PIDInfo->{ProcessId}} = $PIDInfo->{Name}; if ($PIDInfo->{ProcessId} == $$) { $ParentPID = $PIDInfo->{ParentProcessId}; } } print "Parent's name is ", $ProcNames{$ParentPID}, "\n";

        An easier way to get the parent process ID would be to call the getppid() function.

        $parent_id = getppid();
Re: Parent process name
by PodMaster (Abbot) on May 28, 2004 at 13:23 UTC
    You'll have to ask your operating system. Check CPAN. If PS can reveal that info for you, there is a module which parses PS output on CPAN.

    update: Unix::Process, Proc::ProcessTable...

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.