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

Hi,

So I had a pipeline recently that someone was running when they got an error, which the ostensibly emailed to me without alteration. The error looked like it was from the first script call in the pipeline because there should have been an echo in between the 2 calls - at least from what I saw pasted in the email. It turned out that the error was from the second script call in the pipeline.

I have a debug mode in which any error gets prepended with the script's name, but you have to explicitly supply a --debug flag and I was thinking that it would be nice if my script could detect when it's immediate parent process is not an interactive tty - and decide to prepend that string automatically.

In an ideal world, it would also be able to tell if it is inside a series of piped commands as opposed to redirected input/output (</>). Theoretically, I would think that this could be possible simply by the number of concurrent processes the parent process has.

However, I feel like both of these things would be very non-trivial to implement. I know I can use -t or -p for piping, but those don't know anything about parent processes and can't tell the difference between | vs. >.

Any thoughts?

Thanks,

Rob

  • Comment on Can a script tell if it is being run from inside a script versus in an interactive terminal session?

Replies are listed 'Best First'.
Re: Can a script tell if it is being run from inside a script versus in an interactive terminal session?
by BrowserUk (Patriarch) on Nov 07, 2014 at 20:59 UTC

    You might try seeking on STDIN. If its connected to a redirected file, it should succeed; if its a pipe it will fail:

    C:\test>perl -E"seek STDIN, 0,0 or die $!" <junk.txt C:\test>echo junk.txt | perl -E"seek STDIN, 0,0 or die $!" Invalid seek at -e line 1.

    Put the seek in a die block and check for the error condition.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Can a script tell if it is being run from inside a script versus in an interactive terminal session?
by boftx (Deacon) on Nov 07, 2014 at 23:30 UTC

    This is a fairly common question it seems. One answer that might be helpful can be found here.

    You must always remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
Re: Can a script tell if it is being run from inside a script versus in an interactive terminal session?
by RonW (Parson) on Nov 07, 2014 at 21:42 UTC

    I have never had a problem with -p telling my programs if a filehandle refers to a pipe, but that still won't tell you whether the program was run from an interactive shell or not. But your post implies just knowing if it's in a pipeline is good enough.

    But as for telling if a program is being run inside a script, that's really not reliable. If the script is being run from interactive shell, then the program's STDIN, STDOUT and/or STDERR could still be referring to the terminal. And even if none of them do, it could because they are redirected on the command line.

Re: Can a script tell if it is being run from inside a script versus in an interactive terminal session?
by hepcat72 (Sexton) on Nov 12, 2014 at 17:00 UTC

    I know I can use -t/-p to find out about redirection, but it doesn't discriminate between a file redirected in/out versus a pipe to/from another command (which could be another source of error messages).

    So my question I guess is more about parent/sibling process info-gathering. If I'm at a terminal running a script (whether or not it's piped), is there an easy way to determine whether the parent process is a terminal session versus a shell script? And if it's not a terminal session, is there a quick way to find out how many concurrent child processes are running?

    My thinking is that if "I" (being the script that's running) have siblings, then I can assume that there's another command that is being piped from/to with whom my STDERR will mix, so I will need to prepend my STDERR output with the script name so the user knows where the error is coming from.

    In the case where my parent is a shell script, whether or not I have any siblings, I'd still like to know where warnings/errors are coming from.

    I know I can get the parent process ID with getppid(). Is there a perl way to get its number of children and is there a perl way to find out what the parent is?

Re: Can a script tell if it is being run from inside a script versus in an interactive terminal session?
by hepcat72 (Sexton) on Nov 18, 2014 at 01:29 UTC
    So I was thinking about this some more while waiting for my wife to pick me up. I'm not crazy about making system calls, but it's not a critical feature and I could error-check for the existence of the system commands and if it's not present, I can just make an arbitrary decision. But here was my idea:
    sleep 10 | perl -e '$ppid=getppid();$sibs=`pgrep -P $ppid`;print("MY P +ID: $$\nPARENT: $ppid\nSIBLINGS: $sibs\n")' MY PID: 79496 PARENT: 563 SIBLINGS: 79495
    It doesn't work all the time. If I run a short command, like echo, I don't get that PID:
    echo test | perl -e '$ppid=getppid();$kids=`pgrep -P $ppid`;print("MY +PID: $$\nPARENT: $ppid\nSIBLINGS: $kids\n")' MY PID: 79493 PARENT: 563 SIBLINGS:
    Plus, this doesn't tell me about whether or not I'm running inside a shell script. I couldn't find a perl module that does what pgrep does.