Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Odd -w behavior on scripts written on Win32 platform

by c (Hermit)
on Jan 03, 2002 at 00:59 UTC ( #135799=perlquestion: print w/replies, xml ) Need Help??

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

I am facing a really unusual problem that has cropped up on me twice now. I've downloaded a couple of commercial perl scripts which were each zipped up into a Win32 .zip package. I unzip the files on a win machine then scp them over to a linux box. When I run the script on the linux box with a cli ./, I receive:

bash: ./ No such file or directory

However, when I open the file and add a "-w" flag to the #!/usr/bin/perl line, the script is found and ran.

Can someone explain why I am seeing this type of response?

humbly -c

Replies are listed 'Best First'.
(Ovid) Re: Odd -w behavior on scripts written on Win32 platform
by Ovid (Cardinal) on Jan 03, 2002 at 01:04 UTC

    Your problem is that Win32 systems use a \r\n for a line terminator, but Unix like systems only use the newline. One way to fix this is to FTP the scripts over in ASCII mode, or use the following one-liner on the script:

    perl -pi.bak -e 's/\r\n/\n/'

    The reason it doesn't find Perl without the command line switch is that it is actually looking for 'perl\r', but adding the switch puts whitespace after 'perl', thus allowing it to work. Regardless, I've found that even adding the switch can still cause scripts to fail mysteriously if the line-endings are wrong. Best to strip them.


    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Scripts Downloaded from Third Parties Should Be Reviewed Carefully {Re: Odd -w behavior on scripts written on Win32 platform}
by dave_aiello (Pilgrim) on Jan 03, 2002 at 01:47 UTC
    I agree with Ovid on this issue. We run into this problem at one of my consulting clients all the time. Many developers prefer to use a wincvs in spite of the fact that the only execution environment on the client site is an HP/UX box. When Perl scripts are ftp'ed to the host and edited with vi or emacs, I often see extra ^M characters at the end of each line in the file. This is another symptom of the same condition.

    Another way to strip unneeded carriage returns is to use the dos2ux command present in many Unix distros. YMMV.

    I would like to take this opportunity to warn our fellow monks that all of us should see this problem before we encounter it as a runtime error. No Perl script should be downloaded from any third party web site and blindly executed on any machine that you care about. Every Perl script should be given the once-over by a fairly experienced Perl developer. In order to avoid problems like this, you probably ought to look at the script through an editor running on the target OS.

    Dave Aiello
    Chatham Township Data Corporation

Re: Odd -w behavior on scripts written on Win32 platform
by dmmiller2k (Chaplain) on Jan 03, 2002 at 02:01 UTC

    Follow Ovid's advice and strip CR's from the file (perhaps even automatically, by doing an ASCII instead of BINARY transfer with FTP).

    The problem is that the shell expects the shebang line to be terminated with just a newline ('\n'), which it strips off (along with the initial '#!') and then tries to exec what's left. In your case, since the lines are all terminated with CR-LF ('\r\n'), stripping off the newline still leaves a CR at the end of whatever command you have there (i.e., '/usr/bin/perl\r').

    By adding the '-w' switch (or *any* valid Perl option, I suspect), you will have changed the command to '/usr/bin/perl -w\r'. In other words, the '\r' is still there, but it is no longer adjacent to the command name, so the shell's shebang handler passes it to the invoked command as an argument(Perl in this case).

    Perl views the option string '-w\r' the same as if it were the two separate options, '-w' and '-\r'. Since you mention no warning message (when you use -w), I suppose Perl is choosing to ignore the latter, perhaps because it is a form of whitespace.

    Update: Perhaps I forgot to mention this, but if the shell cannot find the command specified on the shebang line, of say '', it will report the error with the message,

    bash: ./ No such file or directory

    as shown in the original note, 'Odd -w behavior on scripts written on Win32 platform'. What this message means is more like "got a 'No such file or directory' error while trying to execute the file, './'." The reason it cannot find it, of course, is that there is no binary executable file named '/usr/bin/perl\r (note the a CR character).'


    You can give a man a fish and feed him for a day ...
    Or, you can
    teach him to fish and feed him for a lifetime
      Following TMTOWTDI, you could create a symbolic link to perl^M in your path. Then hack perl to handle/strip ^M at the end of every line. But it's probably easier to just fix the files :-)
Re: Odd -w behavior on scripts written on Win32 platform
by mrbbking (Hermit) on Jan 03, 2002 at 02:17 UTC
    All of the answers here point to the end-of-line sequence difference on Windows and Unix.

    ...but doesn't the error "bash: ./ No such file or directory" mean that bash can't find the file called in the current directory?

    If it's line endings that cause the problem, then that file has already been found. Wouldn't the error be either from the Perl compiler complaining about syntax, or from bash saying that it can't find whatever appears to be on the shebang line?

      Note how the script was called:

      bash: ./ No such file or directory

      By adding the dot slash before the script name, you're telling the shell to open that script and figure out from the shebang line which program to execute it with. Thus, it is not Perl complaining about syntax issues as Perl is never found. The "no such file or directory" is due to the \r at the end of the shebang. Running cat -vE will show those extra newlines as a cntl-M:

      $ cat -vE #!/usr/bin/perl -w^M$ use strict;^M$ ^M$ my $log = './logfile';^M$

      Without the warnings switch, the shebang would look like this:

      $ cat -vE #!/usr/bin/perl^M$

      The shell thinks the cntl-M is part of the filename, thus giving you the 'no such file' error.


      Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

      Not quite.. It's the C system library that's generating the error message in this case. All your shell is doing is calling an exec() variant with the command you're trying to execute. The C library opens the script, sees that there's a shebang line at the top with an interpreter specified, and it tries to invoke the interpreter. Since the interpreter isn't found (because it has a trailing, spurious CR at the end of it in this case), the exec() call has to return with a "No such file or directory" error, which is what you see. It "might" be feasible for the shell to explore a little further into the cause of the error by testing to see if the file does indeed exist, and if it does, throw a more descriptive error message, but it doesn't. All bash knows is that the system told it ENOENT (No such file or directory) when the shell asked the system to execute your script.
      execve("./test", 0x00053AA8, 0x00053AB0) Err#2 ENOENT
Re: Odd -w behavior on scripts written on Win32 platform
by elwarren (Priest) on Jan 03, 2002 at 03:29 UTC
    Keep in mind that WinZip ships with the "tar file smart CR/LF conversion" turned on by default. If you downloaded from a unix box and uncompressed locally, then transferred, it may not work.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://135799]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (2)
As of 2023-05-28 02:31 GMT
Find Nodes?
    Voting Booth?

    No recent polls found