#!/usr/bin/perl is not needed to run perl in Windows, but - windows

A similar question about the use of
#! /usr/bin/perl
has been answered. But I think I have a slightly different question, although probably still similar to people in the know given my lack of understanding of computation in general.
I don't have UNIX on my Windows so could not test the following directly, but while the shebang line is indeed not needed for me to run Perl under Windows, with the shebang line in the hello.pl, I still could NOT run the file if I move from
c:\Users\XYZ\Desktop\BegPerl
to
c:\Users\XYZ\Desktop
My script is stored under
c:\Users\XYZ\Desktop\BegPerl
My perl folder is stored under
c:\Strawberry\perl\bin\perl.exe
So my questions are:
How does Windows find "perl.exe"?
Why could Windows find hello.pl ONLY when I type perl hello.pl under c:\Users\XYZ\Desktop\BegPerl but NOT under c:\Users\XYZ\Desktop even with the shebang line included?
The answer I got about the "purpose" of the shebang line is
for UNIX-like systems to locate the executable for scripts
So, I guess the answers to my two questions might have something to do with the difference between UNIX-like systems and Windows.

By associating the pl file extension with perl.exe in the OS registry. The directory where perl.exe is should be in the system PATH.
Both should happen when you install perl but if they are not, that is what you need to do.

dir/perl script.pl or /dir/perl script.pl
Unix: The OS will search for perl in the specified path. The shebang line will not be used.*
Win: The OS will search for perl in the specified path. The shebang line will not be used.*
perl script.pl
Unix: The OS will search for perl at the paths in the PATH env var. The shebang line will not be used.*
Win: The OS will search for perl relative to the current directory and at the paths in the PATH env var. The shebang line will not be used.*
script.pl
Unix: The OS will for look for a shebang line, and execute the indicated program and arguments followed by name of the script and command line arguments.
Win: The OS will look for a file association for a file of that extension, and execute the indicated program and arguments. %1 will be replaced with the file's name. %* will be replaced with the command line arguments.
* — The shebang line will not be used by the system. Perl will actually do its own interpretation of the shebang line in case it wasn't used. This allows a -w there to take effect even when the shebang line wasn't used.

Related

How to set up Cygwin to use DOS file endings?

I have following problem:
When I run a shell script, that has been stored with CR+LF line endings, I get following error:
myscript.sh: line 1: cd: $'somedir\\someotherdir\r': No such file or directory
I have researched the problem and there is a solution for Cygwin shell, found here:
Create a .bashrc file
Put this inside:
export SHELLOPTS
set -o igncr
Reload Cygwin shell
However, I use Cmder and I'd like to apply this in it. But, I do not know how. As noted here, Cygwin used to have an option to set the use of DOS file endings as a default during installation, but got rid of it (no idea why).
The weirdest thing of all is that I have the same setup on my older computer, also Windows 10, and everything works well, even with CRLF endings...
I ran into the same problem with upgrading from a very old Cygwin version to the latest.
For just a very few limited "sed" invocations, I explicitly added a \r to the output to keep some other downstream, non-cygwin tools happy.
sed s_(complicated-regex-with-capture)_\1\r_g infile > outfile
A regex guru could probably improve upon this approach to optionally capture and emit the "\r" only if it is found in the data.
sed s_(capture1)(capture\r-or-empty:\r*)$_\1\2_g infile > outfile
You can also use dos2unix which can be installed with Cygwin.

Running a .bat script under Cygwin bash

I would like to use an existing DOS/Windows .bat script under a Cygwin bash shell. The .bat script creates a number of variables which need to exist after the .bat script ends.
This works, but the variables are not retained.
$ ./.phs_project_setup.bat .
It appears that this does not extend to sourcing a .bat script so that the variables it creates still exist in the environment.
$ . ./.phs_project_setup.bat .
-bash: #ECHO: command not found
-bash: SET: command not found
-bash: $'\r': command not found
-bash: REM: command not found
Any ideas on overcoming this obstacle?
What I have done is written the environment to a file, then iterated over the file using 'cygpath -u' on each value. Perhaps I have missed some, but it appears that cygpath will only change something that actually looks like a path. It does not change Oracle connect string for example; "user/pass#DB". I added 'export ' to the beginning of each line so that it can be sourced into a bash shell. It is not one step yet, but better.
Remember that Unix systems are generally case sensitive. cygwin's bash can run windows executables directly, but it's STILL case senstive. SET is not a valid bash command, while set is.
You can force it to source the file and try and run it, but it'll only be able to run shell built-in commands which have a 1:1 name correspondence to cmd commands. So set works, but #echo won't, because # means nothing to bash. Same goes for rem.
I would suggest trying to run the batch script using the batch interpreter (aka the COMSPEC environment variable, which is simply CMD) and then echoing out the environment it has set up as presented in this question: How I can use PowerShell with the Visual Studio Command Prompt?
You can then try and set up the environment in a similar fashion. Note that you may have a problem with the direction of slashes, drive names and other stuff like that
Sounds like you need to run the batch file and then start cygwin. If so, call the batch file from whatever file you use (cygwin.bat for example) to start cygwin. Then the variables should be available.
Alternatively, I've also moved the required bits into the proper unix configuration files to achieve the same results.

Perl - edit in Windows but run directly on Unix shell?

I write my Perl code in Textpad (which I believe is only avai in Windows). I run it on Linux cmd prompt by calling the Perl interpreter explicitly, e.g. "perl script.pl". I was wondering if it's possible to run it simply as in "./script.pl". When I add the shebang in Windows, the Linux prompt complains "command not found", but it works fine if I call it with Perl, and also works fine after I dos2unix the script, so the issue seems to be the shebang not being parsed correctly. Any suggestions? Why does the rest of the Windows-formatted code work but not the shebang?
Your problem is that Windows prefers a different line ending convention (CRLF, or \r\n) than other operating systems (LF, or \n). Your editor is creating files with \r\n line endings by default.
The shebang is parsed by the operating system, which is not as forgiving as Perl about the stray \r at the end of the command. It tries to run /usr/bin/perl\r, which doesn't exist.
Your text editor should be able to save the script with Unix line-endings. This won't cause problems with using it on Windows, though a few Windows text editors (including Notepad) won't recognize the line endings properly. This will make it work properly on Linux.
The first line of your file is
#!/usr/bin/perl<CR><LF>
<LF> is the line terminator, so the OS tries to launch /usr/bin/perl<CR>. There is no such program. dos2unix changes the first line to
#!/usr/bin/perl<LF>
<LF> is the line terminator, so the OS tries to launch /usr/bin/perl and succeeds.

Equivalent of .bat in mac os

I currently use a .bat file that is utilized to invoke a java file. If I wanted to utilize the same functionality on Mac OS what format changes would I make? (unless the .bat equivalent on Mac OS is the .sh format?)
java -cp ".;.\supportlibraries\Framework_Core.jar;.\supportlibraries\Framework_DataTable.jar;.\supportlibraries\Framework_Reporting.jar;.\supportlibraries\Framework_Utilities.jar;.\supportlibraries\poi-3.8-20120326.jar;D:\downloads\Selenium 2.0\selenium-server-standalone-2.19.0.jar" allocator.testTrack
Any assistance would be appreciated.
May be you can find answer here? Equivalent of double-clickable .sh and .bat on Mac?
Usually you can create bash script for Mac OS, where you put similar commands as in batch file. For your case create bash file and put same command, but change back-slashes with regular ones.
Your file will look something like:
#! /bin/bash
java -cp ".;./supportlibraries/Framework_Core.jar;./supportlibraries/Framework_DataTable.jar;./supportlibraries/Framework_Reporting.jar;./supportlibraries/Framework_Utilities.jar;./supportlibraries/poi-3.8-20120326.jar;PATH_TO_YOUR_SELENIUM_SERVER_FOLDER/selenium-server-standalone-2.19.0.jar" allocator.testTrack
Change folders in path above to relevant one.
Then make this script executable: open terminal and navigate to folder with your script. Then change read-write-execute rights for this file running command:
chmod 755 scriptname.sh
Then you can run it like any other regular script:
./scriptname.sh
or you can run it passing file to bash:
bash scriptname.sh
The common convention would be to put it in a .sh file that looks like this -
#!/bin/bash
java -cp ".;./supportlibraries/Framework_Core.jar;... etc
Note that '\' become '/'.
You could execute as
sh myfile.sh
or set the x bit on the file
chmod +x myfile.sh
and then just call
myfile.sh
I found some useful information in a forum page, quoted below.
From this, mainly the sentences in bold formatting, my answer is:
Make a bash (shell) script version of your .bat file (like other
answers, with \ changed to / in file paths). For example:
# File "example.command":
#!/bin/bash
java -cp ".;./supportlibraries/Framework_Core.jar; ...etc.
Then rename it to have the Mac OS file extension .command.
That should make the script run using the Terminal app.
If the app user is going to use a bash script version of the file on Linux
or run it from the command line, they need to add executable rights
(change mode bits) using this command, in the folder that has the file:
chmod +rx [filename].sh
#or:# chmod +rx [filename].command
The forum page question:
Good day, [...] I wondering if there are some "simple" rules to write an equivalent
of the Windows (DOS) bat file. I would like just to click on a file and let it run.
Info from some answers after the question:
Write a shell script, and give it the extension ".command".
For example:
#!/bin/bash
printf "Hello World\n"
- Mar 23, 2010, Tony T1.
The DOS .BAT file was an attempt to bring to MS-DOS something like the idea of the UNIX script.
In general, UNIX permits you to make a text file with commands in it and run it by simply flagging
the text file as executable (rather than give it a specific suffix). This is how OS X does it.
However, OS X adds the feature that if you give the file the suffix .command, Finder
will run Terminal.app to execute it (similar to how BAT files work in Windows).
Unlike MS-DOS, however, UNIX (and OS X) permits you to specify what interpreter is used
for the script. An interpreter is a program that reads in text from a file and does something
with it. [...] In UNIX, you can specify which interpreter to use by making the first line in the
text file one that begins with "#!" followed by the path to the interpreter. For example [...]
#!/bin/sh
echo Hello World
- Mar 23, 2010, J D McIninch.
Also, info from an accepted answer for Equivalent of double-clickable .sh and .bat on Mac?:
On mac, there is a specific extension for executing shell
scripts by double clicking them: this is .command.

Shell script shebang for unknown path

Is it possible to specify a shebang line without knowing the path of the program you want to do the executing?
maybe don't specify the path
#!node
or specify several options
#!/usr/local/bin/node
#!/usr/bin/node
Extra points for cross platform solution (various flavors of linux, BSD, OSX etc...)
/usr/bin/env is specifically thought of for cross-platform solutions.
env executes utility after modifying the environment as specified on
the command line. The option name=value specifies an environmental
variable, name, with a value of value. The option `-i' causes env
to completely ignore the environment it inherits.
If no utility is specified, env prints out the names and values of
the variables in the environment, with one name=value pair per line.
so something in lines of:
#!/usr/bin/env node
Will be cross-platform and "the right way to go".
Contrary to what people may think there is not standard location for env so we can only grab some info regarding it's location:
/usr/bin/env - MacOS (10.12)
both /bin/env, /usr/bin/env - Fedora (25)
I am sure others will be able to extend the list.
Put a space after the shebang. If the program is in environment variable PATH, it should go.
#! perl
Of course, a special case for Perl would be
:
eval 'exec perl -S $0 ${1+"$#"}'
if 0;
This works on unix and OSX, even when there is no /usr/bin/env as noted by #Jens
Dont use shebang.
node <<eof
your node program here
eof

Resources