Экранирование кавычек и двойных кавычек

94

Как правильно избежать кавычек в -paramзначении в следующей командной строке?

$cmd="\\server\toto.exe -batch=B -param="sort1;parmtxt='Security ID=1234'""
Invoke-Expression $cmd 

Конечно, это не удается. Я попытался избежать кавычек (одинарных и двойных) с помощью escape-символа `и сделал различные комбинации, но ничего не работает.

Eetawil
источник
См. Также Invoke-Expression, который считается вредным .
Питер Мортенсен
@PeterMortensen есть проблема с этой статьей в том, что, похоже, нет лучшего способа, когда вы хотите запустить собственное приложение и передать параметр, который включает двойные кавычки в качестве аргумента
Андрей Савиных
@ Андрей Савиных: Один из способов запустить его через CMD вместо: $someCommandStringWithDoubleQuotes | cmd. Это действительно работает из сценариев PowerShell (например, при вызове CMake (для этого требуются двойные кавычки (в противном случае он автоматически завершится ошибкой))). Альтернативой CMD является bash.exe ( MinGW ), но при некоторых обстоятельствах он может запускаться очень и очень медленно.
Питер Мортенсен

Ответы:

60

Ускользание от таких параметров обычно вызывает разочарование и кажется потраченным впустую временем. Я вижу, что у вас v2, поэтому я бы предложил использовать технику, о которой Джоэл «Jaykul» Беннет недавно написал в блоге .

Короче говоря: вы просто оборачиваете строку с помощью @ '...' @:

Start-Process \\server\toto.exe @'
-batch=B -param="sort1;parmtxt='Security ID=1234'"
'@

(Помните, что я предположил, какие кавычки необходимы, а какие вещи вы пытаетесь избежать.) Если вы хотите работать с выводом, вы можете добавить -NoNewWindowпереключатель.

Кстати: это была настолько важная проблема, что, начиная с v3, вы можете использовать, --%чтобы парсер PowerShell не делал ничего с вашими параметрами:

\\server\toto.exe --% -batch=b -param="sort1;paramtxt='Security ID=1234'"

... там должно работать нормально (с тем же предположением).

BartekB
источник
Спасибо за ответ. start-process, как ни старался, всегда жаловался. Итак, я сделал cmd / C $ cmd (где $ cmd - это вся моя команда, включая .exe.). Я использую powershell 2.0. Даже строка здесь не работала, если я правильно помню.
eetawil
3
Это кажется излишне сложным по сравнению с использованием обратной кавычки (`) для избежания двойных кавычек.
saille
6
Это отлично работает, если вы следуете ожидаемым правилам. Первый @ 'должен быть в «строке 1», ваш параметр должен быть в «строке 2», а окончание' @ должно быть в «строке 3». В окончании '@ не должно быть пробелов. Человек этот синтаксис придирчив!
Ian Newland
Работает отлично! Если необходимо расширить переменные в строке, вы можете использовать @"и "@вместо этого.
угрюмо
97

Я могу использовать обратную кавычку (`), если я помещаю их в следующие места:

$cmd="\\server\toto.exe -batch=B -param=`"sort1;parmtxt='Security ID=1234'`""

$cmd возвращается как:

\\server\toto.exe -batch=B -param="sort1;parmtxt='Security ID=1234'"

Это то, что вы искали?

Ошибка, выданная PowerShell, относилась к неожиданному токену sort1, и именно так я определил, где поставить обратные кавычки.

Синтаксис @ '...' @ называется "здесь строкой" и возвращает именно то, что было введено. Вы также можете использовать их для заполнения переменных следующим образом:

$cmd=@'
"\\server\toto.exe -batch=B -param="sort1;parmtxt='Security ID=1234'""
'@

Открывающий и закрывающий символы должны располагаться на отдельной строке, как показано выше.

Оуэн Б.
источник
Извините за задержку ... я заставил это работать, наконец, вызвав cmd / C "MYCOMMAND" из PowerShell. Это не работало напрямую с использованием PowerShell.
eetawil
1
Но не Invoke-Expressionудаляет ли двойные кавычки $cmdпри его вызове? Или как пользовались $cmdбез использования Invoke-Expression?
Питер Мортенсен
8

Сегодня я оказался в аналогичном затруднительном положении, когда пытался запустить команду через модуль Node.js:

Я использовал PowerShell и пытался запустить:

command -e 'func($a)'

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

command -e `"func($a)`"
пранспах
источник
2
интересно: "['`"][^'`"]['`"]"работает… но '[`'"][^`'"][`'"]'не работает! сводил меня с ума
Дэвид Дж