Почему PowerShell (с Perl) удаляет двойные кавычки в простом операторе печати?

Я давний пользователь Linux, но плохо знаком с Windows и PowerShell. Я только что впервые установил Windows7 и Strawberry Perl 5. Теперь я хочу выполнить простую печать из командной строки с помощью Windows PowerShell.

Похоже, Perl установлен правильно:

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

И командная строка работает:

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

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

Но когда я пробую все это само по себе, он выводит предупреждение обработчика файлов:

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

Таким образом, похоже, что двойные кавычки удаляются.

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

Это работает, но это некрасиво! Давай еще раз попробуем:

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

Это больше похоже на то, но я запутался.

Почему PowerShell избегает двойных кавычек внутри одинарных? Есть ли пользователи PowerShell?


person CoffeeMonster    schedule 08.08.2009    source источник
comment
Вы пробовали perl -e "print 'Hello, World'"?   -  person Weegee    schedule 11.08.2009


Ответы (3)


Я думаю, здесь есть пара проблем. Во-первых, кавычки имеют символическое значение как в PowerShell, так и в Perl. Кавычки и экранирование работают в PowerShell несколько иначе, чем в оболочке UNIX. Посмотрите man about_quoting в PowerShell.

Вторая проблема заключается в том, что командная строка perl в Windows работает по-другому. Любые двойные кавычки внутри командной строки, которые вы хотите передать в perl, должны быть экранированы в терминах perl как \ ". Это не относится к PowerShell. Так Perl работает в Windows. Обычно у вас будут аналогичные проблемы с cmd.exe.

Эти версии должны работать:

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

Вы можете сделать то же самое с меньшим экранированием, используя одинарные кавычки.

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

Вы также можете поместить новую строку в powershell вместо передачи escape-последовательности новой строки в perl для синтаксического анализа.

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
person Brian Reiter    schedule 11.08.2009

Интересно. Кажется, что когда вы покидаете мир PowerShell, он преобразует одинарные кавычки в двойные кавычки, чтобы их правильно интерпретировала командная оболочка Windows. (Или что-то подобное). Чтобы продемонстрировать с помощью python (который, похоже, демонстрирует ту же проблему):

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

Это та же ошибка, которую я получаю, если пытался сделать что-то подобное из командной оболочки Windows:

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

Как будто PowerShell делает это при выполнении команды:

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
person zdan    schedule 09.08.2009

Что произойдет, если вы запустите «неправильную» команду в cmd.exe вместо PowerShell? Я спрашиваю, потому что работающая escape-последовательность (\") принадлежит Perl; в PowerShell это будет "" `.

person dahlbyk    schedule 09.08.2009