using perl to build commandline args in gdb in Cygwin - perl

I've used perl commands before to build commandline arguments in gdb (example: run perl -e 'print "A"x20'), but my Cygwin install doesn't parse the commands, it treats them as literal strings (argv[1] = "perl", argv[2] = "-e", etc...)
Is this some type of Cygwin environment that needs to be set up, or something else?

I don't know about Cygwin specifically, but in a Windows Command you have to double quote the perl expression and struggle inside the one-liner if you need double quotes (you can use qq for example). So on my WinXP machine this:
perl -e "print 'A'x20"
prints 20 A's.

Related

Pass command line parameters to perl via file?

Could command lines parameters been saved to a file and then pass the file to perl to parse out the options? Like response file (prefix the name with #) for some Microsoft tools.
I am trying to pass expression to perl via command line, like perl -e 'print "\n"', and Windows command prompt makes using double quotes a little hard.
There are several solutions, from most to least preferable.
Write your program to a file
If your one liner is too big or complicated, write it to a file and run it. This avoids messing with shell escapes. You can reuse it and debug it and work in a real editor.
perl path\to\some_program
Command line options to perl can be put on the otherwise useless on Windows #! line. Here's an example.
#!/usr/bin/perl -i.bak -p
# -i.bak Backs up the file.
# -p Puts each line into $_ and writes out the new value of $_.
# So this changes all instances in a file of " with '.
s{"}{'}g;
Use alternative quote delimiters
Perl has a slew of alternative ways to write quotes. Use them instead. This is good for both one liners as well as things like q[<tag key='value'>].
perl -e "print qq[\n]"
Escape the quote
^ is the cmd.exe escape character. So ^" is treated as a literal quote.
perl -e "print ^"\n^""
Pretty yucky. I'd prefer using qq[] and reserve ^" for when you need to print a literal quote.
perl -e "print qq[^"\n]"
Use the ASCII code
The ASCII and UTF-8 hex code for " is 22. You can supply this to Perl with qq[\x22].
perl -e "print qq[\x22\n]"
You can read the file into a string and then use
use Getopt::Long qw(GetOptionsFromString);
$ret = GetOptionsFromString($string, ...);
to parse the options from that.

Perl verbose output?

Is there are a way to get Perl debug output, similar to bash -x but in Perl?
I do not need strikt or diagnose messages (they compile the code but do not print the line that the Perl interpreter executes).
Assuming you are using some kind of unix you can use the Devel::Trace perl module.
If it is not installed you can install it from CPAN like this:
sudo perl -MCPAN -e 'install Devel::Trace'
Once you have it you can run your script like this:
perl -d:Trace myscript.pl
And it will do exactly what bash -x does (note that the name of the Trace package is case sensitive).

Cannot execute system command in cygwin

I have the following simple perl script that I cannot execute in cygwin:
#!/usr/bin/perl
use strict;
system("../cat.exe < a.txt > b.txt");
When I run it, the script tells me:
./my_test.pl
'..' is not recognized as an internal or external command,
operable program or batch file.
However I can run the command in the cygwin shell:
$ ../cat.exe < a.txt > b.txt
$ ../cat.exe b.txt
hello
The executable cat.exe exists in the directory above and a.txt in the current working
directory.
My version of perl:
$ perl -v
This is perl, v5.8.8 built for MSWin32-x86-multi-thread
(with 12 registered patches, see perl -V for more detail)
You're using a perl built for Windows (ActiveState? Strawberry?), not the Cygwin version. It invokes cmd.exe for system(), which thinks that .. is the command and / introduces an option.
Try changing the the system() call to:
system("..\\cat.exe < a.txt > b.txt");
But you should normally be using the Cygwin version of perl when running a script from bash.
What is the output of the following commands?
echo "$PATH"
type -a perl
/usr/bin/perl -v
From what we've seen so far, it looks like you've installed some Windows-specific Perl with its perl.exe in your Cygwin /usr/bin directory. If so, then (a) uninstall it (you can reinstall it elsewhere if you like), and (b) re-install the "perl" package via Cygwin's setup.exe.
(And add use warnings; after use strict; in your Perl scripts. This isn't related to your problem, but it's good practice.)
The error message obviously comes from cmd.exe, which apparently is your default shell. What does echo $SHELL say? Maybe you need to define that variable to become /bin/bash.exe.

Using perl in windows oddities

I've got windows bat file, (using activeperl)
#echo off
perl -p -e 's/DIV\[/div\[/g' orginal.txt > output.txt
perl -p -e 'rename("output.txt", "orginal.txt")';
...
Running a .bat file, and I just cant get it to run properly..
Can't open ;: No such file or directory, <> line 12248.
Can't find string terminator "'" anywhere before EOF at -e line 1.
Not sure what I'm doing wrong..
You can't use single-quotes to enclose the Perl code in Windows. As a result, you need to escape the double-quotes or find other alternatives, such as qq(...).
perl -pe "s/DIV\[/div\[/g" original.txt > output.txt
perl -pe "rename(qq(output.txt), qq/original.txt/)"
Note that in this case, the arguments to rename can simply be rename('a.txt', 'b.txt') since they are literals and no variable interpolation is required.
You ought to use double quotes to quote the program text under Windows cmd. In your example, you can just swiztch double and single quotes. In cases where you really need double quotes in the perl text, use qq{ .... } instead.
The other posters are correct: windows requires double quotes for -e scripts to perl, which often screws things up. There is one more thing you can do, though: Use the -i switch, like this:
#echo off
perl -pi.bak -we "s/DIV\[/div\[/g" original.txt
The -i.bak switch will edit the file in place - no rename required - AND it will store a backup of the file in "original.txt.bak". If you do not want a backup, remove the ".bak" part and just use -pi.

How do I protect quotes in a batch file?

I want to wrap a Perl one-liner in a batch file. For a (trivial) example, in a Unix shell, I could quote up a command like this:
perl -e 'print localtime() . "\n"'
But DOS chokes on that with this helpful error message:
Can't find string terminator "'" anywhere before EOF at -e line 1.
What's the best way to do this within a .bat file?
For Perl stuff on Windows, I try to use the generalized quoting as much as possible so I don't get leaning toothpick syndrome. I save the quotes for the stuff that DOS needs:
perl -e "print scalar localtime() . qq(\n)"
If you just need a newline at the end of the print, you can let the -l switch do that for you:
perl -le "print scalar localtime()"
For other cool things you can do with switches, see the perlrun documentation.
In Windows' "DOS prompt" (cmd.exe) you need to use double quotes not single quotes. For inside the quoted Perl code, Perl gives you a lot of options. Three are:
perl -e "print localtime() . qq(\n)"
perl -e "print localtime() . $/"
perl -le "print ''.localtime()"
If you have Perl 5.10 or newer:
perl -E "say scalar localtime()"
Thanks to J.F. Sebastian's comment.
For general batch files under Windows NT+, the ^ character escapes lots of things (<>|&), but for quotes, doubling them works wonders:
C:\>perl -e "print localtime() . ""\n"""
Thu Oct 2 09:17:32 2008
First, any answer you get to this is command-specific, because the DOS shell doesn't parse the command-line like a uniq one does; it passes the entire unparsed string to the command, which does any splitting. That said, if using /subsystem:console the C runtime provides splitting before calling main(), and most commands use this.
If an application is using this splitting, the way you type a literal double-quote is by doubling it. So you'd do
perl -e "print localtime() . ""\n"""
In DOS, you use the "" around your Perl command. The DOS shell doesn't do single quotes like the normal Unix shell:
perl -e "print localtime();"