in reply to Re: Re: Test for standard input
in thread Test for standard input

Thanks alot ! The -t flag worked. Here's the new code :
#!/bin/perl -w $ARGS = @ARGV; if (-t and $ARGS eq 0 ) { print "No input found\n"; exit 1; } $names++, shift if $ARGV[0] eq "-l"; $search = shift; $showname = @ARGV > 1; @ARGV = "-" unless @ARGV; @ARGV = grep { -T or $_ eq "-" } @ARGV; exit 0 unless @ARGV; while (<>) { next unless /$search/o; if ($names) { print "$ARGV\n"; close ARGV; } else { print "$ARGV: " if $showname; print; } }

Replies are listed 'Best First'.
Re: Re: Re: Re: Test for standard input
by sauoq (Abbot) on Oct 03, 2002 at 18:36 UTC

    You might consider looking at the problem a little differently. Frankly, your error, "No input found," makes very little sense. When called as simply

    $ grep
    the input, stdin, is still available to the program. What's missing is the pattern to search for in the input.

    Instead of going to all the trouble to test for a tty, you might find it's preferable to simply check to make sure there is at least one argument. If there is exactly one argument, it is the pattern and stdin is the input. If there are more than one then the subsequent ones are filenames of the files you wish to use for input. That way, it is only an error when no arguments are supplied. This is how grep(1) works so the behavior will be familiar even to users who have never used your program before.

    Also, you might want to add these to your test cases:

    $ grep < some_file $ cat | grep
    -sauoq
    "My two cents aren't worth a dime.";
    
Re: Re: Re: Re: Test for standard input
by mikfire (Deacon) on Oct 03, 2002 at 18:05 UTC
    Sorry, I cannot resist. Your code is ummmm doing lots of things that I do not think are what you intend.
    $ARGS = @ARGV; if ( -t and $ARGS eq 0 ) { }
    The more idiomatic way of saying this is
    die "No input found\n" if ( -t and @ARGV == 0 );
    I would also like to point out that you are testing the wrong kind of equality in your code -- you used the string equality test ( eq ) instead of the numeric test ( == ). In this case it worked, but it will someday drive you nuts trying to hunt this kind of bug down.

    $names++, shift if $ARGV[0] eq "-l";
    If I have figured this out correctly, you are trying to parse some command line options. I would strongly recommend using Getopt::Long, a core module that does this job very well.

    I am assuming you really mean to shift the argument you just parsed out of @ARGV. Unfortunately, shift with no arguments assumes you mean @_, which is not @ARGV. Again, it likely works in this case, but I really doubt this is your intended affect.

    The same holds true for the next line.

    @ARGV = "-" unless @ARGV;
    This code will never be executed. I am assuming it is a hold-over from your previous problems. The 'if' at the top of the program makes certain that @ARGV has to have something in it.

    The assignment back to @ARGV is a little.... ugly IMHO. It took me several tries to figure out what it is doing. I would likely write this expression as

    exit 0 unless ( grep { -T or $_ eq "-" } @ARGV );
    but this is likely more a stylistic thing.

    Oh, good use of the -w flag. It appears, though, you forgot to use strict. It will seem a pain at first, but it will really help as your programs get longer and more complex.

    Mik
    mikfire

      <pedantry>shift in a non subroutine context shifts from @ARGV.</pedantry>
        Damn. I have been programming perl for years now and I did not know this. Thanks!

        Mik
        mikfire