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

I've been sort of conscripted at work to help convert some automated processes from VMS's DCL to Perl in preparation for moving to an AIX system. Writing Perl, I thought, would be fun. Even if it's on VMS. ;-)

Well, I don't know much about VMS but one thing that I thought I knew was that VMS does support pipes. And it does. Sorta.

There is a VMS command PIPE that allows you pipe one command into another from the command line. It works like so: $> PIPE DIR | SEARCH SYS$INPUT TEST.PL (searches a directory listing for the file 'TEST.PL')

With Perl, I can even get a pipe from a process (open INFILE, " command |";) to work.

Unfortunately, I need a pipe going the other direction and I just can't seem to get it to work. From what I can tell, I should be able to accomplish this somehow but I'm sure I'll have to jump through a few proverbial hoops for VMS to do it.

What I'd like to know is whether it's just something I'm doing wrong, or if it doesn't work at all and I'm wasting my time, or if there's something special I have to do to get it to work.

My code, and the error I get, are below. I sure hope some of the great programmers can help me on this one! TIA!

The Code:

#!perl -w use strict; use vmsish; # The 'TYPE ...' is basically a 'cat > FILE.TMP'... open OUTFILE, ' | TYPE SYS$INPUT /OUTPUT=FILE.TMP' or die "$0: can't open: $!"; print OUTFILE "Wish this would work...\n"; close OUTFILE or die "$0: can't close: $!";

The Results: test.pl: can't open: file specification syntax error at test.pl line 6.

bbfu
Seasons don't fear The Reaper.
Nor do the wind, the sun, and the rain.
We can be like they are.

Replies are listed 'Best First'.
Re: VMS: Pipe to process
by kschwab (Vicar) on Feb 03, 2001 at 04:10 UTC
    I know nothing about VMS, but...:
    open OUTFILE, ' | TYPE SYS$INPUT /OUTPUT=FILE.TMP' ^
    You need to remove the errant space (see the ^ above) for perl's open() to interpret this as a pipe open, rather than a file name.

    Or maybe it was just a cut-n-paste error ?

      Okay! That works perfectly! I swear that somewhere I remember reading that Perl would allow leading space and that it was actually a good idea to put it in there (something about preventing some abuse from input strings??). I'll remember that it's not.

      Well, now I feel silly. Such a simple thing, I should've tried that before posting! :-) Thanks a million, kschwab!

      bbfu
      Seasons don't fear The Reaper.
      Nor do the wind, the sun, and the rain.
      We can be like they are.

        It's generally a good idea to put a leading space before the actual name of the file/command, not before any control characters that determine how the filehandle should be opened. Consider:
        # this is pseudo-code $filename = '>test' or '+test' open(HANDLE, ">$filename"); # >>test or >+test (ruh-roh!) # likewise $filename = 'ls|' or '>test; open(HANDLE, "$filename"); # ls| (pipe) or clobbers 'test' # generally safe (in that behavior is not unexpected): open(PIPE, " $command |") open(PIPE, "| $command\0"); # safe version of "|ls" open(FILE, "> $filename\0"); # ">file" open(FILE, " $filename\0"); # "file"
        In the last case, the presence of a space doesn't affect what is open, but since the first character is a space, any leading "mode" characters in $filename will be ignored, much like what was happening with your code.

        Also see sysopen and perlipc (e.g., using fork/exec), which (in my opinion) are significantly more readable/safer than using weird manglings of open. Note that issues of shell meta-characters and other security considerations are out of the scope of this message. Each of the "PIPE" examples above are still incredibly insecure if untrusted input is allowed to use any shell metacharacters in the string. See perlsec and use Taint-checking.