When I run
perl -e 'which("clang")'
in Windows Command Prompt I get an empty line, but on Linux I get:
Undefined subroutine &main::which called at -e line 1.
I am asking because I am trying to figure out why which does not work in OpenSSL build script:
# see if there is NDK clang on $PATH, "universal" or "standalone"
if (which("clang") =~ m|^$ndk/.*/prebuilt/([^/]+)/|) { ... }
where the condition is always false even if clang is in the PATH.
which is not a Perl builtin function.
% perl -we 'print which("clang")'
Undefined subroutine &main::which called at -e line 1.
Keep in mind the Windows command line does not use the same quoting rules as the Linux command line, unless you're using something like WSL or bash for Windows.
The subroutine which is defined at https://github.com/openssl/openssl/blob/master/Configure#L3264 (or a similar line in other versions of the code). You'll need to make sure you've got all the build dependencies installed, all the application paths and library/include paths configured correctly, that you're following the installation directions accurately, and that you're doing things in the proper order.
You'll especially want to look in https://github.com/openssl/openssl/blob/af33b200da8040c78dbfd8405878190980727171/NOTES-WINDOWS.md and https://github.com/openssl/openssl/blob/master/NOTES-PERL.md to make sure you're following the OpenSSL project's recommendations for their build system on Windows if native Windows is where you intend to do the builds.
Related
I am writing a perl script, and I want to run a simple shell command to use a certain version of NVM:
Here is my code snippet:
print "\n*** Switching to correct nvm environment for dashboard builds\n";
system("nvm use 8.12.0") == 0 or die $?;
But I am getting the following error:
Can't exec "nvm": No such file or directory
Can someone help?
Update (June 30, 2021):
I also tried adding the command:
my $nvm_version = "8.12.0";
system ("bash", "-lic", "nvm use $nvm_version");
But nothing happens:
I'm not familiar with nwm, but I think I get the gist of what it does. And if so, the attempt is fundamentally flawed. Even if you fixed this to run the proper shell so that nvm could run, I believe all the tool does is change the shell's environment variables, a shell you immediately exit. This means it would have no effect even if if it ran successfully.
Again, it this tool does what I think it does, such tool are meant to be used in interactive shells. In other instances, you simply use the path the to correct executable instead of relying on the PATH.
With that in mind, you can use the following to run the command in bash:
# Non-interactive shell.
system("bash", "-c", "nvm use 8.12.0")
or
# Interactive shell.
# This is improper and fragile as interactive shells
# often create aliases that override basic commands.
system("bash", "-ic", "nvm use 8.12.0")
Just to reiterate, at least one of these will allow the command to run (if it normally works from bash), but I believe it's unlikely this will produce the results you expect.
The nvm command is shell function which is different from a shell command. Also the nvm command is not an exported function so it will not be seen by sub shells. For example, in Bash shell:
$ nvm ls
-> v15.0.1
$ my-test-script.sh
./my-test-script.sh: line 3: nvm: command not found
where my-test-script.sh is:
#! /bin/bash
nvm use 16.4
The error nvm: command not found is because nvm is not exported. I can source the script in the current shell context to make it work:
$ source my-test-script.sh
Now using node v16.4.0 (npm v7.18.1)
$ node --version
v16.4.0
So a Perl script cannot change the node version of the current shell, but it can calculate the version and pass it back to shell, which can set the version. For example:
$ nvm use $(perl -E'$v=15.0; print $v')
Now using node v15.0.1 (npm v7.0.3)
I have the following Perl script. I am trying to run it in Windows 7 using ActivePerl:
#!c:\Perl64\bin\perl.exe -w
use strict;
my $mp3splt_exe = 'c:\Program Files (x86)\mp3splt\mp3splt.exe';
my $mp3splt_args = '-o "#n #f" -g "r%[#o #N]" -f -t 6.0';
print #ARGV;
my $filename = $ARGV[0];
print "$mp3splt_exe $mp3splt_args $filename\n";
(as you can see, I am trying to create a wrapper for mp3splt :-) )
When I run it like this:
C:\Program Files (x86)\mp3splt>run_mp3splt.pl a
I get this:
Use of uninitialized value $filename in concatenation (.) or string at C:\Program Files (x86)\mp3splt\run_mp3splt.pl line 12.
c:\Program Files (x86)\mp3splt\mp3splt.exe -o "#n #f" -g "r%[#o #N]" -f -t 6.0
So, first of all, when I print #ARGV, nothing gets printed, and second of all, when I assign $filename = $ARGV[0], $filename is undef, so I get the warning.
So... what am I doing wrong? Why isn't the commandline parameter being passed to the script?
As others have pointed out perl blah.pl asdf works, while blah.pl asdf fails. This is because when you run the perl script directly, Windows realizes it must call perl, and uses the rule perl "%1", which only passes the script name to perl, not any of the parameters.
To fix this, you have to tell windows to use the rule perl "%1" %*
How to do that can be a little tedious:
Option 1
According to perlmonks, you should be able to use assoc and ftype on the commandline. In fact, if you type help ftype, it tells you how to setup perl:
assoc .pl=PerlScript
ftype PerlScript=perl.exe %1 %*
To run assoc requires cmd run as administrator on Window 7.
However, this didn't work for me. Windows ignored the association. I had to modify the registry. This may be due to the misguided advice to run the Default Programs utility on Win 7, which lets you specify the program to use for given file extensions. Unlike XP, this will not allow you to specify multiple command options (to be used in the right-click menu) -- it will only allow you to specify the program that is used when you double-click on a file (or run foo.pl from commandline).
Option 2
Modify the registry: HKEY_CLASSES_ROOT
If you've used the assoc/ftype commands, you may have entries for perl or PerlScript. As I said earlier, these will be ignored. Look for pl_auto_file, and drill down to the command:
HKCR\pl_auto_file\shell\open\command
Here the (Default) should be set to something like: "C:\Perl\bin\perl.exe" "%1"
Add the missing %* on the end of that and you should be good to go: "C:\Perl\bin\perl.exe" "%1" %*
No reboot necessary.
Option 3
If you're lazy and trusting, you can try using this as a reg file, and importing it into your registry:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\pl_auto_file\shell\open\command]
#="\"C:\\Perl\\bin\\perl.exe\" \"%1\" %*"
This should be sufficient to make blah.pl asdf work.
I've had the problem that if I executed on Win7:
perl myprog.pl a b c
the program got the parameters (in #ARGV) correctly, but if I executed:
myprog.pl a b c
the program would NOT receive the parameters.
I searched the web for a solution and soon found that it was no ActiveState perl problem but more likely a filetype association problem in Windows (Win7), (thanks to the PerlMonks website).
However all solutions changing the
assoc .pl=Perl
and the
ftype Perl="C:\Perl\bin\perl.exe" "%1" %*
did not solve the puzzle for me. I did notice that the assoc .pl was not used somehow because if I added assoc .plx=Perl and renamed my program to myprog.plx
myprog.plx a b c
worked perfectly !
So then I read this problem on the Microsoft forum were the Win7 "feature" Default Programs was mentioned, I found the solution to my problem:
Open Default Programs by clicking the Start button , and then click "Default Programs".
Select "Associate a file type or protocol with a program" and select ".pl" and click on "Change program". There was already a Perl Command Line Interpreter specified as Recommended Programs but instead I clicked on Browse and selected the Perl.exe myself. After closing the "Associate a file type ..." screen,
myprog.pl a b c
executed like a charm, all parameters were correctly retrieved by my program.
Hope that helps...
Perl ARGV problem solution in Windows 8.1:
HKEY_CLASSES_ROOT\Applications\perl.exe\shell\open\command =
"C:\Perl\bin\perl.exe" "%1" %*
No re-boot needed.
I'm pretty sure Windows 7 doesn't understand the shebang line. What happens if you run this with perl run_mp3splt.pl a?
Running Lubuntu -
Beginner Perl programmer
Script is XXX.pl located at ~/projects/XXX/XXX.pl
First line is the shebang
#!/usr/bin/perl
Permission to run is set to Anyone.
In directory ~/projects/XXX, the command
~/projects/XXX$ perl XXX.pl
works as desired, but the command
~/projects/XXX$ XXX.pl
Fails with XXX.pl: command not found
What am I missing ?
The two usual options to execute your Perl script are:
perl XXX.pl
or
./XXX.pl
Both ways assume that your current working directory contains the script XXX.pl, otherwise it won't work.
As already pointed out by jm666 in the comments, you can usually not execute a program or script from your current working directory without prepending ./, primarily because of security reasons. Now, you may wonder why it's necessary.
Explanation:
Your shell uses the contents of an environment variable called $PATH to find out about where external commands (non-builtin programs) are located in your filesystem. If you want to see what's in $PATH, just type the following in your shell:
echo $PATH
Now you can see that the $PATH variable does NOT contain your current working directory. The consequence is that your shell is not able to find the program XXX.pl. By prepending ./ you instruct the shell to execute the program which comes after.
But there are two requirements if you want to execute your Perl script with ./script.pl:
The script has to be executable (check with ls -l)
The first line (shebang line) has to be #!/path/to/your/perl because your shell needs that information to find the perl interpreter in order to run your script
However, #1 and #2 are NOT required when you execute your script with
perl XXX.pl
because it invokes the perl interpreter directly with your script.
See how to make Perl scripts executable on Linux and make the script itself directly executable with chmod for some more details.
Can the script be found?
Is . in your path? If it's not, add it to your path, or use ./XXX.pl instead of XXX.pl.
Can the script be executed?
Do you have execute permission to the file? Fix using chmod u+x XXX.pl.
Is the interpreter correct?
which perl will tell you which interpreter is used when you use perl XXX.pl. That's the path that should be on your shebang (#!) line.
Problem: Windows XP is not passing command line arguments to perl scripts.
Symptom: a simple command like:
say "Argument 1 (\$ARGV[0]) is: $ARGV[0], argument 2 (\$ARGV[1]) is: $ARGV[1].";
Resulted in:
Use of uninitialized value $ARGV[0] in concatenation (.) or string at...
Solution:
The root problem is in Windows XP. The default method for starting perl passes only the first variable, which is the script name. Result is that $ARGV[0] is uninitialized.
The fix is to edit the Windows registry at:
\HKEY_CLASSES_ROOT\Perl\shell\Open\command
And make the entry:
"C:\Perl\bin\perl.exe" %*
Result is:
C:\whatever>perl argtest.pl 1 2
Argument 1 ($ARGV[0]) is: 1, argument 2 ($ARGV[1]) is: 2.
Thanks especially to David W who pointed me in the right direction.
Note that #ARGV in Perl is not quite like argv in C.
C Perl
Name of the program argv[0] $0
1st argument argv[1] $ARGV[0]
2nd argument argv[2] $ARGV[1]
n-th argument argv[n] $ARGV[n-1]
So if you provide one command line arguments to a Perl script, it will be found in $ARGV[0]. $ARGV[1] will be uninitialized.
Download Cygwin and test your code in the Cygwin environment. I bet this is a Windows issue. (If you're a Unix head, you'll like Cygwin because it gives you the Unix/Linux like environment on your Windows machine. I don't use Windows without it.)
Windows uses suffixes to determine what program opens what files. Is your Perl script called argtest, argtest.bat or argtest.pl?
On Windows, make sure all of your Perl scripts use the *.pl suffix, so Windows will use whatever Perl parameter to execute them. Windows doesn't use the shebang.
Another possible issue: On Windows XP, I had a problem with Perl scripts with parameters because Windows had this as an execution string:
perl %1
which would execute the Perl program with my script, but ignore the parameters. I had to change this to:
perl %*
Unfortunately, Windows Vista through Windows 8 changed the way this is set. However, I have Windows 7 and don't have this issue. I did make sure to install Perl under C:\Perl and not C:\Program Files\Perl because of the space in the directory name. I also have Strawberry Perl installed.
There is a special Windows environment variable called PATHEXT. This allows you to type in foo instead of foo.pl. If Windows can't see how to execute your file, Windows goes through %PATHEXT and tries appending various suffixes until it finds one that works. You might want to append .PL to that environment variable, so you can type in foo instead of foo.pl all the time.
There are two ways that Windows knows it is supposed to use Perl to execute a program.
The command line begins with the perl executable and the name of the script to be run is provided as a command line argument. This is how it works on Unix and other environments, too.
Your system associates one or more extensions, such as .pl, .pm, and/or .cgi with the Perl application, and Windows will launch Perl when you type a filename with one of those extensions or click on a file with one of those extensions in the Windows explorer.
You have invoked your script simply as
argtest 1 2
and not one of
perl argtest 1 2
argtest.pl 1 2
That makes me think that Perl is not the first application that gets to look at the file referred to by argtest. Perhaps there is a file called argtest.bat or argtest.exe which has the task of getting Perl to run your Perl code. For some reason this intermediate program is not passing the command line arguments that you provide on to the Perl application.
Provide the code for this intermediate file and we can help some more.
UPDATE: David W proposes a 3rd way -- setting the PATHEXT environment variable to inclue .pl files and invoking argtest from the command-line -- see his answer.
Then if Window's file association with the .pl extension was messed up, say, set as just C:\Dwimperl\perl\bin\perl" and not "C:\Dwimperl\perl\binperl %*" then the OP would get the behavior that he describes.
In perl file name is not part of the array of arguments. At least in the test I did you must remove ARGV[2] or pass three arguments, like argtest 1 2 3
I have the following Perl script. I am trying to run it in Windows 7 using ActivePerl:
#!c:\Perl64\bin\perl.exe -w
use strict;
my $mp3splt_exe = 'c:\Program Files (x86)\mp3splt\mp3splt.exe';
my $mp3splt_args = '-o "#n #f" -g "r%[#o #N]" -f -t 6.0';
print #ARGV;
my $filename = $ARGV[0];
print "$mp3splt_exe $mp3splt_args $filename\n";
(as you can see, I am trying to create a wrapper for mp3splt :-) )
When I run it like this:
C:\Program Files (x86)\mp3splt>run_mp3splt.pl a
I get this:
Use of uninitialized value $filename in concatenation (.) or string at C:\Program Files (x86)\mp3splt\run_mp3splt.pl line 12.
c:\Program Files (x86)\mp3splt\mp3splt.exe -o "#n #f" -g "r%[#o #N]" -f -t 6.0
So, first of all, when I print #ARGV, nothing gets printed, and second of all, when I assign $filename = $ARGV[0], $filename is undef, so I get the warning.
So... what am I doing wrong? Why isn't the commandline parameter being passed to the script?
As others have pointed out perl blah.pl asdf works, while blah.pl asdf fails. This is because when you run the perl script directly, Windows realizes it must call perl, and uses the rule perl "%1", which only passes the script name to perl, not any of the parameters.
To fix this, you have to tell windows to use the rule perl "%1" %*
How to do that can be a little tedious:
Option 1
According to perlmonks, you should be able to use assoc and ftype on the commandline. In fact, if you type help ftype, it tells you how to setup perl:
assoc .pl=PerlScript
ftype PerlScript=perl.exe %1 %*
To run assoc requires cmd run as administrator on Window 7.
However, this didn't work for me. Windows ignored the association. I had to modify the registry. This may be due to the misguided advice to run the Default Programs utility on Win 7, which lets you specify the program to use for given file extensions. Unlike XP, this will not allow you to specify multiple command options (to be used in the right-click menu) -- it will only allow you to specify the program that is used when you double-click on a file (or run foo.pl from commandline).
Option 2
Modify the registry: HKEY_CLASSES_ROOT
If you've used the assoc/ftype commands, you may have entries for perl or PerlScript. As I said earlier, these will be ignored. Look for pl_auto_file, and drill down to the command:
HKCR\pl_auto_file\shell\open\command
Here the (Default) should be set to something like: "C:\Perl\bin\perl.exe" "%1"
Add the missing %* on the end of that and you should be good to go: "C:\Perl\bin\perl.exe" "%1" %*
No reboot necessary.
Option 3
If you're lazy and trusting, you can try using this as a reg file, and importing it into your registry:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\pl_auto_file\shell\open\command]
#="\"C:\\Perl\\bin\\perl.exe\" \"%1\" %*"
This should be sufficient to make blah.pl asdf work.
I've had the problem that if I executed on Win7:
perl myprog.pl a b c
the program got the parameters (in #ARGV) correctly, but if I executed:
myprog.pl a b c
the program would NOT receive the parameters.
I searched the web for a solution and soon found that it was no ActiveState perl problem but more likely a filetype association problem in Windows (Win7), (thanks to the PerlMonks website).
However all solutions changing the
assoc .pl=Perl
and the
ftype Perl="C:\Perl\bin\perl.exe" "%1" %*
did not solve the puzzle for me. I did notice that the assoc .pl was not used somehow because if I added assoc .plx=Perl and renamed my program to myprog.plx
myprog.plx a b c
worked perfectly !
So then I read this problem on the Microsoft forum were the Win7 "feature" Default Programs was mentioned, I found the solution to my problem:
Open Default Programs by clicking the Start button , and then click "Default Programs".
Select "Associate a file type or protocol with a program" and select ".pl" and click on "Change program". There was already a Perl Command Line Interpreter specified as Recommended Programs but instead I clicked on Browse and selected the Perl.exe myself. After closing the "Associate a file type ..." screen,
myprog.pl a b c
executed like a charm, all parameters were correctly retrieved by my program.
Hope that helps...
Perl ARGV problem solution in Windows 8.1:
HKEY_CLASSES_ROOT\Applications\perl.exe\shell\open\command =
"C:\Perl\bin\perl.exe" "%1" %*
No re-boot needed.
I'm pretty sure Windows 7 doesn't understand the shebang line. What happens if you run this with perl run_mp3splt.pl a?