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

I am new to perl. I am writing cgi scripts and have to add the -w flag on the first line of the script which reads: #!/usr/bin/perl in order for the browser to execute the script. If I leave it off the script will not execute. Why? What changes do I need to make in order for scripts to run without the -w flag? Mike ---- mspencer@neo.rr.com

Replies are listed 'Best First'.
Re: Why do I need -w in a cgi script
by Abigail-II (Bishop) on Oct 09, 2003 at 15:13 UTC
    Are you writing your programs on Windows and copying it "as is" (say, by using binary FTP, HTTP PUT, HTTP file upload, scp, copying on a mounted disk, sneakernet, or something else) to a Unix machine?

    In that case, all the lines will have a trailing ^M (before the newline). Without the -w, you're telling the kernel you want to execute "/usr/bin/perl^M". That's a perfectly valid filename under Unix, but it's unlikely such a program exists.

    With the -w, the line ends with "-w^M", and perl itself can deal with the Windows ending.

    The solution is to strip the ^M's out of your file. FTP ASCII upload will do this automatically for you. Or use a utility like dos2unix, or something like:

    perl -wple 's/^M//' yourfile
    on the Unix side.

    Abigail

      Once, in a previous lifetime, when I was a sysadmin on a server where rather clueless peopleclients were uploading Perl CGI scripts, I fixed this problem by creating a symbolic link of which the name would include the ^M. It was easier then explaining having to use ASCII FTP mode over and over and over again.
      # perl -e '$a=`which perl`;symlink $a,"$a\r"'

      Liz

      Update:
      Change symlink creation to a more Perlish way.

      Update:
      Changed perlish way from # perl -e 'symlink $^X,"$^X\r"' to the above, to take into account the directory where Perl resides. Pointed out by ambrus.

         perl -e 'symlink $^X,"$^X\r"' won't work, as $^X equals to "$^X" in this case, so it will create a broken symlink named perl^M in the current directory. You'll first have to chdir to /usr/bin.
        Sorry to annoy you, but I still don't like it this way. On my system, `which perl` will return "/usr/local/bin/perl", so "/usr/bin/perl\cM" will still not exist. Also, which is just an alias for type -p, so I doubt if it's portable (it might not even work if it's defined in bashrc, that's read only in interactive sessions). (Also, on some machines, /usr/local/bin/perl is a later version of perl than /usr/bin/perl.)
      Actually, that's
      perl -wpi -e 's/\r//' yourfile
      But whos keeping track?

      ------------
      :Wq
      Not an editor command: Wq
      Excellent answer. I would not have thought of the "/usr/bin/perl^M", but it makes perfcet sense.

      I work in a Windows and Unix environment. One of the most simple yet useful things I've ever found on perlmonks was a slightly different version for stripping the ^M's. I use it all the time and it's very nice if you have multiple files that need cleanup.

      perl -pi.bak -e 's/\cM//g' *.cgi

      You don't really need the backup up, but it's nice when you first try it to know that you won't lose your data if it doesn't work.
        I work in a Windows and Unix environment. One of the most simple yet useful things I've ever found on perlmonks was a slightly different version for stripping the ^M's.

        I just ssh into the server and edit the files directly there, but for a more production-oriented environment I can see why some might not favor that approach, as a mis-edit could leave the script broken for a couple of minutes. In my situation this is not a big deal. Of course, if it were, I could have two directories on the server, one for development and one for production, which is probably what I'd do. Or have two servers.


        $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,".rekcah lreP rehtona tsuJ";$\=$ ;->();print$/
        I gave the code as a one-liner to be entered from the command line, and then ^M (as in "control-M", and not a caret followed by an M) will work. You might have to enter it as "CTRL-V CTRL-M" in certain shells though.

        Abigail

Re: Why do I need -w in a cgi script
by vek (Prior) on Oct 09, 2003 at 15:10 UTC

    The -w flag just turns on warnings and will have no bearing on whether the code runs or not. There *is* something else wrong - trust me. Are you using Apache? If so, check the error log - usually /usr/local/apache/logs/error_log for clues. If you're still stuck try posting some code and we'll take a look.

    -- vek --
Re: Why do I need -w in a cgi script
by Yendor (Pilgrim) on Oct 09, 2003 at 20:52 UTC
    Having read Ovid's CGI Course thoroughly, I heartily recommend it as a great starting point for discussions on this type of question. He covers the -w (as well as the -T) flags very well, including reasons why you should use them. It's a great starting point for CGI concepts.

    -Yendor

    IWeThey
    HOPE Ride

Re: Why do I need -w in a cgi script
by hmerrill (Friar) on Oct 09, 2003 at 15:52 UTC
    As others have said, there must be something else wrong with your script - -w will not cause your script to not run. Here's what
    perldoc perlrun
    says about the -w switch:
    -w prints warnings about dubious constructs, such as variable + names that are mentioned only once and scalar variables that are + used before being set, redefined subroutines, references to und +efined filehandles or filehandles opened read-only that you are a +ttempt- ing to write on, values used as a number that doesn’t look + like numbers, using an array as though it were a scalar, if you +r sub- routines recurse more than 100 deep, and innumerable other + things.
    IMHO, you should always use the "-w" switch - I do :-)

    HTH.
      IMHO, you should always use the "-w" switch - I do

      For testing, always use -w. However, if you reach a point where you're no longer doing anything actively in terms of testing or changing the script, it doesn't hurt to turn it off for production use. The real question is whether it's reasonable to turn off Taint checking for production use, or whether it should always be left on, and I think this depends on your specific circumstances. I leave it on, personally.


      $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,".rekcah lreP rehtona tsuJ";$\=$ ;->();print$/

        The real question is whether it's reasonable to turn off Taint checking for production use, or whether it should always be left on, and I think this depends on your specific circumstances. I leave it on, personally.

        Taint checking is a security tool, not a development tool. Unless security is unimportant in production, do not remove it.

        Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

        Whether to leave on taint checking or not in production code isn't a question. Removing it in production isn't an option. It's like saying you keep safety belts on while preparing your car, but you remove them from your car when you're about to drive cross-country.

        Abigail