in reply to Test if STDOUT is attached to console or shell redirected filehandle

Read the output of perldoc -f -X, and look at the "-t" function. Here's an example of how it would work for your case (I'm using bash-shell style quotations on a perl one-liner):
perl -le 'warn "stdout is NOT being redirected/piped" if(-t STDOUT); p +rint "foo"'
If you run that exactly as shown, you'll get the message on STDERR, but if you pipe stdout to another command, like this:
perl ... | grep o
or if you redirect stdout to a file like this:
perl ... > foo.txt
then you won't see any message on STDERR.

Replies are listed 'Best First'.
Re^2: Test if STDOUT is attached to console or shell redirected filehandle
by desemondo (Hermit) on Sep 07, 2009 at 02:21 UTC
    Legend!

    And thanks for clarifying pipe vs redirect terminology.
Re^2: Test if STDOUT is attached to console or shell redirected filehandle
by liverpole (Monsignor) on Sep 07, 2009 at 17:36 UTC
    Thank you ++graff for enlightening me to the usage of -t.

    I've always wondered if it were possible to detect whether a script were being run on the receiving end of a pipe (somehow I never came across -t).  Using -t with <STDIN> is exactly how to do it!

    Here's a test script highlight.pl which, in a Linux terminal window, demonstrates the difference between:

    % ./highlight.pl

    and:

    % cat highlight.pl | ./highlight.pl
    #!/usr/bin/perl -w use strict; use warnings; my $b_windows = ($^O =~ /win/i)? 1: 0; if ($b_windows) { require Win32::Console::ANSI; print "\e[H\e[J"; } my $color1 = $b_windows? "\e[1;42m": "\e[102m"; my $color2 = $b_windows? "\e[1;45m": "\e[105m"; my $a_lines = [ "# Stopping By Woods On A Snowy Evening -- Robert Frost", "# ", "# Whose woods these are I think I know.", "# His house is in the village though;", "# He will not see me stopping here", "# To watch his woods fill up with snow.", "# ", "# My little horse must think it queer1", "# To stop without a farmhouse near", "# Between the woods and frozen lake", "# The darkest evening of the year.", "# ", "# He gives his harness bells a shake", "# To ask if there is some mistake.", "# The only other sound's the sweep", "# Of easy wind and downy flake.", "# ", "# The woods are lovely, dark and deep.", "# But I have promises to keep,", "# And miles to go before I sleep,", "# And miles to go before I sleep.", ]; my $pattern = "wood"; if (-t STDIN) { # Program being run standalone: "<script>" foreach (@$a_lines) { s/($pattern)/$color1$1\e[m\e[K/gi; print " $_\n"; } } else { # On receiving end of another process: "cat <script> | <script>" while (<STDIN>) { if (/"# [a-zA-Z]/) { s/($pattern)/$color2$1\e[m\e[K/gi; print; } } }

    Apparently the -t <filehandle> construct doesn't work on Windows (at least not my version (update:  ActiveState v5.10.0), because in both cases -t STDIN evaluates to FALSE.  That is:

    C:\> highlight.pl

    does the same thing as:

    C:\> type highlight.pl | highlight.pl

    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
      I think thats probably a Windows thing; when I call perl from the pipe first, your code works perfectly.
      fyi, I'm using ActiveState v5.8.8.822
      type highlight.pl | perl highlight.pl
        Interesting!

        In Windows (ActiveState v5.10.0) doing it this way "works":

        type highlight.pl | perl highlight.pl

        Doing it this way does not:

        type highlight.pl | highlight.pl

        s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/