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

Hi folks!

This one should be simple: How can I output a EOF-character (Control-D) from my Perl program to a pipe?

The reason I ask is: I use a program (gprolog) that usually reads stuff (prolog definitions) from the keyboard, until the user presses Control-D, then it reads other stuff (prolog queries) from the keyboard. So, when my Perl script has fed gprolog with all the definitions and needs to do a query, it needs to send an EOF of some kind. Closing the filehandle is obviously not an option, since the script needs to do more IO after the EOF.

Thanks for any help,


Replies are listed 'Best First'.
Re: EOF character
by merlyn (Sage) on Sep 25, 2006 at 06:57 UTC
    You're apparently somewhat confused. EOF is just that, EOF. When you press ^D at a keyboard, it gives the application a 0-byte read, which stdio interprets as "end of file". There's nothing after that. Nothing.

    So, the way to send EOF to your child process is to close the handle. That's it. And you can't do more IO after that, just as you couldn't do more IO after that if you were interacting with it anyway.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

Re: EOF character
by cdarke (Prior) on Sep 25, 2006 at 08:50 UTC
    Mr. Schwartz (above) is absolutly correct.
    Just to add a little detail, there is no such thing as an EOF character in UNIX. The Control-D you are used to pressing is picked up by the terminal driver, the program at the other end does not recieve the character, it gets an end of file condition (not the same thing).
    You can inspect special terminal characters using stty -a (from a shell) and even change the character used using stty eof.
    This is different to Microsoft Windows cmd.exe. If you notice you have to press Control-Z then <Return> - the IO engine actually recieves the Control-Z in that case. In Perl you only see that character if the handle has binmode set (but then, you were not going to use Windows anyway).

      That's not quite how things work in Win32. When reading from a file, Ctrl-Z is never special, just like in unix. The behaviour you described only applies when reading from a terminal.

      { open(my $fh, '>', 'deleteme.tmp') or die("Unable to create work file: $!\n"); binmode($fh); print $fh ("abc\r\n\cZ\r\ndef\r\n"); } { open(my $fh, '<', 'deleteme.tmp') or die("Unable to read work file: $!\n"); # Not binmode. print <$fh>; }
Re: EOF character
by jwkrahn (Abbot) on Sep 25, 2006 at 06:34 UTC
    Did you try:
    print "\cD";
    And did that work?

    Perhaps you need the Expect module?

      Yes, thanks both of you for your suggestions, but unfortunately, none of them worked. I'll have a look at Expect, though.
Re: EOF character
by chargrill (Parson) on Sep 25, 2006 at 06:34 UTC

    Try this:

    print $fh chr 4;

    Note, not tested, but I lifted the ASCII code for ^d from here: HTH. Also assumes you want to print to a filehandle $fh. If your filehandle is named differently, adjust to suit.

    s**lil*; $*=join'',sort split q**; s;.*;grr; &&s+(.(.)).+$2$1+; $; = qq-$_-;s,.*,ahc,;$,.=chop for split q,,,reverse;print for($,,$;,$*,$/)