0

I am working on creating some training material where I am using perl. One of the things I want to do is have the scripts be set up for the student correctly, regardless of where they extra the compressed files. I am working on a Windows batch file that will copy the perl templates to the working location and then update path in the copy of the perl template files to the correct location. The perl template have this as the first line:

#!_BASE_software/perl/bin/perl.exe

The batch file looks like this:

SET TRAINING=%~dp0
copy %TRAINING%\template\*.pl %TRAINING%work
%TRAINING%software\perl\bin\perl -pi.bak -e 's/_BASE_/%TRAINING%/g' %TRAINING%work\*.pl

I have a few problems with this:

  1. Perl doesn't seem to like the wildcard in the filename
  2. It turns out that %TRAINING% is going to expand into a string with backslashes which need to be converted into forwardslashes and needs to be escaped within the regex.

How do I fix this?

  • 2
    Your code is severely lacking in doublequotes. You can use `%TRAINING:\=/%` to automatically replace the backslashes with forward slashes. Please remember that `%~dp0` already includes a trailing backslash, in places you have and others you haven't. – Compo Jan 17 '20 at 01:27
  • The second part of `s///` is not a regex, but a quoted string. That said, it will still be a problem (syntax error) if it expands to something with forward slashes. It might be simpler to set it in the environment, then use `$ENV{TRAINING}` from Perl. – Grinnz Jan 17 '20 at 01:28
  • Maybe ExtUtils::Command will help. Perl'ish implementation of popular UNIX utilities – k-mx Jan 17 '20 at 04:39
  • Take a look at `help for`, particularly the `/f' option. – jwdonahue Jan 17 '20 at 07:03

1 Answers1

2

First of all, Windows doesn't use the shebang line, so I'm not sure why you're doing any of this work in the first place.

Perl will read the shebang line and look for options if perl is found in the path, even on Windows, but that means that #!perl is sufficient if you want to pass options via the shebang line (e.g. #!perl -n).

Now, it's possible that you use Cygwin, MSYS or some other unix emulation instead of Windows to run the program, but you are placing a Windows path in the shebang line (C:...) rather than a unix path, so that doesn't make sense either.

There are three additional problems with the attempt:

  1. cmd uses double-quotes for quoting.
  2. cmd doesn't perform wildcard expansion like sh, so it's up to your program do it.
  3. You are trying to generate Perl code from cmd. ouch.

If we go ahead, we get:

"%TRAINING%software\perl\bin\perl" -MFile::DosGlob=glob -pe"BEGIN { @ARGV = map glob, @ARGV; $base = $ENV{TRAINING} =~ s{\\}{/}rg } s/_BASE_/$base/g" -i.bak -- %TRAINING%work\*.pl

If we add line breaks for readability, we get the following (that cmd won't accept):

"%TRAINING%software\perl\bin\perl"
   -MFile::DosGlob=glob
   -pe"
      BEGIN {
         @ARGV = map glob, @ARGV;
         $base = $ENV{TRAINING} =~ s{\\}{/}rg
      }
      s/_BASE_/$base/g
   "
   -i.bak -- %TRAINING%work\*.pl
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • 1
    Good answer! one thing though, for the sake of possible whitespace in paths, I would double quote the path. `"%TRAINING%software\perl\bin\perl"` – Gerhard Jan 17 '20 at 14:00
  • 1
    @Gerhard Barnard, It won't work with spaces even with the quotes you recommend because you can't have spaces in the path in the shebang line. There might be system-specific ways of addressing that, but I am not familiar with them. But I did add the quotes, thanks. – ikegami Jan 18 '20 at 00:48
  • I love the simple fact I don't have to worry about the path in Windows, inlight of this, I am going to abandon the this whole thing. Thank you! –  Jan 19 '20 at 19:03