Run external command from within Perl - windows

I am using Doxygen to generate HTML documentation and then run a Perl script to get function names.
To run Doxygen configuration, I need to run doxygen file_name in cmd.
But I want to run everything from Perl.
I tried this code
my $cmd = "perl -w otherscript.pl";
my $result = system("start $cmd");
But it just opens a cmd window. I need to execute cmd code directly through Perl (not a Perl command line, but through a Perl IDE). Is there a way to achieve this?

Your usage of system and start is OK.
From your description in the comment, I think it's because you're not using the correct escaping method when giving configure files to Doxygen that it throws such an error:
Error: configuration file C:SERSGHOSHBCD not found!
Try with
my $result = `doxygen C:\\Users\\aghosh\\abcd`;
In the two back-slashes, the former one is to escape the latter one, so that it's recognized by Windows as the directory separator.

Related

Perl: Why do I get error "The file name, directory name, or volume label syntax is incorrect."

I am trying to run the below perl code from Windows batch file but getting error The file name, directory name, or volume label syntax is incorrect.
The script ran fine in eclipse.My ultimate goal is to run this perl script periodically using windows task scheduler, hence running it from a batch file.
Is there any other ways with which we can achieve my goal of running perl script on windows periodically?
I want my script to be functional across platforms, coz I have plans to run it from a mac as well.
use strict;
use warnings;
use Data::Dumper;
use File::Find::Rule;
my $basedir="G:\/My_Workspaces";
my #exclude_dirs= qw(.foo);
#Fetching all the workspaces under base dir excluding the ones in #exclude_dirs
my #subdirs =
File::Find::Rule
->mindepth(1)
->maxdepth(1)
->not_name(#exclude_dirs)
->directory
->in($basedir);
#Formating list of workspaces by removing the full path
s{^\Q$basedir\E/}{} for #subdirs;
If that is exactly the contents of your file, then you're asking Windows' command interpreter to process Perl source code, which it can't do
If you really need to create a batch file that has your Perl code embedded in it, then take a look at the pl2bat utility, which will do exactly that
A command like
pl2bat myperl.pl
will create a file myperl.bat that will run on the Windows command line and has your Perl source code embedded inside it. But that file is non-portable because it uses Windows commands that aren't recognised on a Mac or Linux platform
Either something doesn't know how to execute your Perl script, or your Perl script is being interpreted by something other than perl.
This could due to a problem with your file associations (or a lack thereof). Determining the exact cause would require more information.
In any case, executing perl with your script as a parameter rather than executing the script directly should solve the problem.
In other words, execute
perl script.pl
instead of
script.pl

Ruby: How to open .exe file(that open CMD) and run command init

I am trying using ruby script to a task.
I have an .exe file that i want to run.
when opening this file it open in CMD and i can pass commands to it.
That file located in C:\temp\test.exe
I need to go to the directory and then open the file and then insert to it command like:
"getobject" task = "aa"
this program will give me the result to the CMD.
i will need to copy the result to text but i think i can handle it late.
I tried to search it online cant found anything.
Thanks
If you want to open an executable, usually you can use the `command` syntax in Ruby. So call:
`C:\temp\test.exe`
That should run the executable from the Ruby script. Then you can interact with that executable as if you ran it from a CMD instead of a Ruby file.
In order to run and capture the output of a command you'll need to use a system command. There are many system commands that you can use, but my preference is Open3:
require 'open3'
output, status = Open3.capture2("C:\temp\test.exe")
In the event that you want to pass command line arguments to capture2 you'll want to write that like this: Open3.capture2("C:\temp\test.exe", "arg1", "arg2"). That is the safest way to pass arguments.
I think what you are looking for is input/ output redirection
check redirection
Not tested
system 'C:\temp\test.exe < "\"getobject\" task = \"aa\""'

How to tell if vim is being run in command line vs. powershell

I would like to make a function which does the following
if (vim is running in powershell)
call system("only works in powershell")
else
echo "Skipping powershell command"
Does anyone know how to tell what program vim is being run from?
EDIT: echo &term outputs "win32" in both cases.
From what I see you don’t need to check what vim was run from. You need to check the value of &shell because vim will run command in powershell if &shell option tells it to run command in powershell. If name of the shell is posh then checking may be done with
if stridx(&shell, 'posh')!=-1
call system('only works in powershell')
else
echo 'Skipping powershell command'
endif
. But I would rather suggest to run powershell directly with something like
call system('posh -c '.shellescape('only works in powershell'))
(note: I am not sure about what 'posh -c ' string should actually look like) or temporary set &shell option:
let savedsh=[&shell, &shellcmdflag, &shellxquote, &shellxescape, &shellquote, &shellpipe, &shellredir]
set shell=posh shellcmdflag=-c shellxquote=\" shellquote=\" shellpipe=> shellredir=>
try
call system('only works in powershell')
finally
let [&shell, &shellcmdflag, &shellxquote, &shellxescape, &shellquote, &shellpipe, &shellredir]=savedsh
endtry
(again, not sure about exact values of options): these ways command will always run in powershell.
You can check $term. For example on my cygwin and git bash, I get $term as cygwin.
For Powershell, you may set in your profile the following and check against that:
$env:TERM = "posh"
Note that &shell will cmd.exe for both cmd and powershell.

Problem with input filter using doxygen 1.6.3 on windows XP

I am trying to use doxygen to generate documentation for some matlab classes I have written. I am using the doxygen-matlab package, which includes a perl script to kludge matlab .m files into c++ style commented files, so that doxygen can read them.
In my doxyfile, I have set (according to the instructions)
FILTER_PATTERNS = *m=C:/doxygenMatlab/m2cpp.pl
However, when the code runs, rather than running the script on the input files, it appears to just open the script using whatever the default windows setting for .pl is.
IE, if I associate .pl with notepad, the script is opened by notepad once for each input file doxygen is trying to parse. If I associate .pl with perl.exe, the script runs and throws the no argument error
Argument must contain filename -1 at C:\doxygenMatlab\m2cpp.pl line 4.
The doxygen documentation says
Doxygen will invoke the filter program by executing (via popen()) the command <filter> <input-file>
So I am wondering if there is some problem with popen() and windows that I could fix.
Could you try the workarounds I posted on the Matlab File Exchange regarding the doxygen package ?
Set the following variables in the Doxyfile :
INPUT_FILTER=perl m2cpp.pl
FILE_PATTERNS=*.m
If it doesn't work you should try to install ActivePerl : with this version of perl, everything is working fine.
I tried to reproduce the error using the Windows command prompt ("cmd") and noticed the following:
If you call "perl m2cpp.pl" you get error -1 because you did not specify a m-file to be translated into a cpp-file.
If you call "perl m2cpp.pl mfile" and the path of mfile contains spaces, you get error 1.
After I moved the mfile into a location which does not contain spaces, I got the desired output.
Now back to Doxygen. I tried what you suggested, Fabrice, without any luck. I read the doxygen help and found out that the INPUT_FILTER variable is only read and used if FILTER_PATTERNS is empty.
Therefore, I now use INPUT_FILTER = "C:\Programme\MATLAB\R2009a\sys\perl\win32\bin\perl U:\doxygen_matlab\m2cpp.pl" and an empty FILTER_PATTERNS variable. With this configuration, you can even leave the PERL_PATH variable empty. Moreover, there seems to be no issues with file names that contain spaces.
Unfortunately, all files are parsed with the above configuration, not only m-files. However, setting FILTER_PATTERNS to something like *.m=C:\Programme\MATLAB\R2009a\sys\perl\win32\bin\perl U:\doxygen_matlab\m2cpp.pl does not work because doxygen automatically adds the name of the filtered mfile and interprets the command as perl "m2cpp.pl mfile". Of course, the file "m2cpp.pl mfile" does not exist, because these are two files.
Maybe you can find a solution to this problem. In the meantime, I suggest the workaround above and that you keep your C-files away from the folder that contains the m-files.
write a simple batch file, e.g. mfilter.bat, which takes one argument from command line:
C:\Programme\MATLAB\R2009a\sys\perl\win32\bin\perl U:\doxygen_matlab\m2cpp.pl %1
Change setting in Doxyfile:
FILTER_PATTERNS = *.m=mfile.bat
This did it for me (on a Windows platform)
I think I solved this problem : it came from a bad association between .pl and the program to execute (maybe due to a bad installation of the perl shipped whith Matlab ?).
To correct this, you should change the association for the .pl files : in a Windows command prompt ("cmd"), just type de 2 following lines :
assoc .pl=PerlScript
ftype PerlScript=C:\Program Files\MATLAB\R20xx\sys\perl\win32\bin\perl.exe %1 %*
(the old installation forgot the %* at the end, the arguments were not passed to the m2cpp.pl script).
And then everything should be fine with the FILTER_PATTERNS set the usual way, for example FILTER_PATTERN=*m=C:\DoxygenMatlbab\m2cpp.pl
Could you tell me if this fixed your problem ?
According to the Doxygen forums, there is a difference in behavior between using INPUT_FILTER and FILTER_PATTERNS.
I found that if I do some extra (escaped) quoting, I can get FILTER_PATTERNS to work. For example, instead of:
FILTER_PATTERNS = "*.m=sed -e 's|%%|//!|'"
Try:
FILTER_PATTERNS = "*.m=\"sed -e 's|%%|//!|'\""
(All of my experimentation was done with doxygen version 1.8.6)

Why doesn't a * in my pipe open in Perl work on Windows?

I am having this strange issue with Perl. I am trying to execute an external program from inside my Perl script and this external program takes string + wildcard as parameters. My Perl program looks like this
my $cmd_to_run = 'find-something-in-somedb myname* |'
open(procHandle, $cmd_to_run); # I am using open because I want to
# parse the output using pipes
For some weird reason, running this Perl script (under Windows) call to open function ends up with error:
'sqlselect' is not recognized as an internal or external command
I guessed that its something to do with * present in my command string and hence I removed it and now my command string looks like this
my $cmd_to_run = 'find-something-in-somedb myname|'
Now when I run my Perl script it works perfectly fine. Problem comes only when wildcard character is present.
Some points to note :
I ran the same command with wildcard char, in the same cmd prompt (where i am executing this perl script) and it works perfectly fine..
Same command works when I program it in C using _open function in Windows.
Problem seems to be only when wildcard * is present , at least that's what I am guessing
No, I haven't tried this in Unix..
Any clues???
EDIT : I found that this is something to do with ENV . The program that i am trying to run uses "sqlselect" only when "*" wild card is present in search string...
Both find-something-in-somedb and sqlselect are present in same location. In which case how perl is able to find "find-in-db" and not "sqlselect"
Sorry i realize that original problem is turning out to be something else now.. Something to do with "ENV" and not with Wildcard *
It is recommended to use the 3-argument form of open
open(procHandle, '-|', 'find-something-in-somedb', 'myname*');
as that bypasses the shell (which will perform * expansion).
However, on Windows, applications often perform their own quote-parsing and * expansion, so you may need
open(procHandle, '-|', 'find-something-in-somedb', '"myname*"');
or even
open(procHandle, '-|', 'find-something-in-somedb "myname*"');
as I'm not sure exactly how and when Perl hands things off to cmd.
It's very likely that Perl is expanding the wildcard itself, which you don't want to do. The answer provided by ephemient is very good, but in order to debug this, try calling this really simple program:
print join ' ', #ARGV;
Put that into its own file, then call it from your original program (I named mine argv.pl):
my $cmd_to_run = './argv.pl myname* |'
open(procHandle, $cmd_to_run);
That will definitively tell you on your platform how Perl is parsing things. On Unix, the * is expanded to match the files in the current working directory. Not sure about Windows though.
What happens if you use three-argument open?
open my $procHandle, '-|', 'find-something-in-somedb myname*'
or die "Cannot open pipe: $!";

Resources