views:

625

answers:

3

Hi, I am am a longtime Linux user but am new to Windows and PowerShell. I just installed Windows7 and Strawberry Perl 5 for the first time. I now want to do a simple command-line print with Windows PowerShell.

It looks like Perl installed correctly:

PS C:\Users\Me> perl -v 
This is perl, v5.10.0 built for MSWin32-x86-multi-thread Copyright
1987-2007, Larry Wall 
...

And command-line stuff works:

PS C:\Users\Me> perl -e 'die'
Died at -e line 1.

PS C:\Users\Me> echo 'print "Hello, World\n"' | perl
Hello, World

But when I try it all by itself it prints a filehandler warning:

PS C:\Users\Me> perl -e 'print "Hello, World\n"'
No comma allowed after filehandle at -e line 1.

So it looks like its removing the double quotes.

PS C:\Users\Me> perl -e 'print \"Hello, World\n\"'
Hello, World

That works but its Ugly! Lets try again:

PS C:\Users\Me> perl -e 'print qq{Hello, World\n}'
Hello, World

Thats more like it, but I'm confused.

Why is PowerShell is escaping the double quotes within the single quotes? Any PowerShell users out there?

A: 

What happens if you run the "wrong" command in cmd.exe instead of PowerShell? I ask because the escape sequence that works (\") is Perl's; in PowerShell it would be `".

dahlbyk
+1  A: 

Interesting. It seems as if when you leave the powershell world, it converts the single quote to a double quote to be properly interpreted by the windows command shell. (Or something like that). To demonstrate with python (which seems to exhibit the same problem):

PS C:\> python -c  'print "Hi from python"'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'Hi' is not defined

which is the same error I get if I tried to do something similar from the windows command shell:

C:\>python -c  "print "Hi from python""
Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'Hi' is not defined

It's as if powershell is doing this when executing the command:

PS C:\> $s = 'python -c "print "Hi from python""'
PS C:\> cmd /c $s
Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'Hi' is not defined
zdan
+2  A: 

I think there are a couple of problems here. One is that quotes have symbolic meaning in both powershell and perl. Quotes and escaping work a little differently in powershell than in a UNIX shell. Check out man about_quoting in powershell.

The second issue is that the perl command-line behaves differently on Windows period. Any double quote inside the command-line that you want to pass on to perl needs to be escaped in perl terms as \". This is not specific to powershell. It is the way perl works on Windows. You will generally have similar problems with cmd.exe.

These versions should work:

PS> & perl -e "print \`"hello, world\n\`""
hello, world
PS> $s = "print \`"hello, world\n\`""
PS> echo $s
print \"hello, world\n\"
PS> & perl -e $s
hello, world

You can do the same thing with less escaping using single quote.

PS> & perl -e 'print \"hello, world\n\"'
hello, world
PS> $s = 'print \"hello, world\n\"'
PS> echo $s
print \"hello, world\n\"
PS> & perl -e $s
hello, world

You can also put the newline in powershell instead of passing a newline escape sequence to perl for parsing.

PS> & perl -e "print \`"hello, world`n\`""
hello, world
PS> $s = "print \`"hello, world`n\`""
PS> echo $s
print \"hello, world
\"
PS> & perl -e $s
hello, world
Brian Reiter