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

I have a 2 part question, a) in general, who do you set up a script for working in windows and the unix environment, say if the script takes command line options and interacts with the filesystem in both cases? b) specifically I am using the GetOpts::std module for reading in switches, however on win32 starting with the directory "My documents", when you type in the path (say myScript -p C:/My Documents) what is read in from he command line is "C:/My". How does perl deal with the spaces in win32 directory names, and how do you set up a script for handling the issue on win32, as well as handling unix filesystem? aristAugust

Replies are listed 'Best First'.
Re: win32/unix compatible script
by Anonymous Monk on Jul 13, 2001 at 23:05 UTC
    Use quotes around command line options that have spaces in them should work in both windows and unix. myScript -p "C:/My Documents"
Re: win32/unix compatible script
by bikeNomad (Priest) on Jul 13, 2001 at 23:45 UTC
    Your problem is not a Perl problem; it's a shell (CMD.EXE or COMMAND.COM) problem. Just like almost any DOS/NT program that would be passed the same argument, you have to quote filenames that contain spaces. You'll notice that your windows file type associations generally have the argument given as "%1" ; this is for just this reason.

    Once you've actually got the filename, nothing (neither Perl nor NT) cares that there may be embedded spaces in the filenames.

Re: win32/unix compatible script
by dragonchild (Archbishop) on Jul 13, 2001 at 23:08 UTC
    The second part of your question, regarding filenames - Perl "does the right thing". So, just use Unix-style filenames and you'll be just fine.

    With regards to commandline options ... the thing I did when I had a Perl app that ran on both was to have a batchfile in Windows that had the commandline options I wanted and had it launch the Perl app. It was just simpler that way, plus it stayed within the GUI nature of Windows, to just double-click on some batchfile on the desktop.

    Just as a warning, if you have an application that is a commandline app that binds STDIN and STDOUT to be descriptors, this will not work under windows. You will have to set up a telnet server, then telnet to yourself to get this descriptor behavior. There is a way to check which OS you're on (I don't remember which), then bring in the right modules to do the right thing.

      You can find the OS you are on with these special vars:
      $OSNAME $^O The name of the operating system under which this copy of Perl was built, as determined during the configuration process. The value is identical to `$Config{'osname'}'. See also the Config manpage and the -V command-line switch documented in the perlrun manpage.
      From the perldoc perlvar POD.

      --xPhase

      Just as a warning, if you have an application that is a commandline app that binds STDIN and STDOUT to be descriptors, this will not work under windows.
      What about STDIN/STDOUT doesn't work under Windows? Could you clarify?

      —John
      Win32 Programmer

        What I'm talking about is the following code:

        my $in = new FileHandle "<&STDIN"; my $out = new FileHandle ">&STDOUT"; autoflush $out;

        What this allows you to do is to treat STDIN and STDOUT (keyboard and monitor, essentially) as if they were any old descriptor. Thus, you can have a commandline app that doesn't care if it's talking to a person at the keyboard or a telnet session.

        This works under Unix cause everything in Unix is treated (for all practical purposes) as if it's happening on a VT-100 terminal. Each window is treated by the kernel as its own process with its own input and output. The input and output (generally) is the same for all your windows, but the kernel doesn't make that optimization.

        Windows does, which means that STDIN isn't an attribute of a given window, but of the OS as a whole. Thus, the problem.

        It's easy to get around - you just have to telnet to yourself. :)