Обработка команд Powershell (передача переменных)
Я создаю сценарий Powershell для развертывания некоторого кода, и частью процесса является вызов инструмента сжатия командной строки под названием RAR.EXE для резервного копирования некоторых папок.
Я пытаюсь динамически создавать параметры, а затем powershell вызывает команду с переменными, но у меня возникают проблемы. Это не работает...
запустите следующий скрипт, и вы увидите, о чем я говорю. Параметры, передаваемые в качестве переменной искореженный. Если я передаю всю команду + параметры, я получаю печально известный " не распознается как командлет..." сообщение.
Спасибо за любую помощь!
echo "this should succeed"
& cmd /c echo foo
echo "why does this echo out an additional double quote?"
$param = "/c echo foo"
& cmd "$param"
echo "this does the same"
$param = "/c echo foo"
& cmd $param
echo "escaping the slash doesn't work either..."
$param = "`/c echo foo"
& cmd $param
echo "this fails, but why?"
$cmd = "cmd /c echo foo"
&$cmd
6 ответов
оператор вызова " & " в этом случае не требуется. Он используется для вызова команды в новой области. Обычно это используется для вызова команды, заданной строкой или scriptblock. Он также имеет побочное преимущество, что любые переменные, созданные в сценарии PowerShell, отбрасываются после завершения команды и области.
однако, поскольку cmd является EXE, он выполняется в совершенно другом процессе. FWIW, вы получаете подобный выход сразу от УМК.exe:
> cmd "/c echo foo"
foo"
таким образом, дополнительная цитата В конце-cmd.проблема exe. Обычно вам нужно держать команду отдельно от параметров, когда PowerShell выполняет синтаксический анализ, чтобы вызвать команду, например
45> & { $foo = "foo" }
46> $foo # Note that $foo wasn't found - it went away with the scope
47> . { $foo = "foo" } # dotting executes in the current scope
48> $foo
foo
заметным исключением здесь является то, что Invoke-Expression ведет себя как функция "оценить эту строку". Используйте с осторожностью, особенно если пользователь предоставляет строку. Ваш день может сосать, если они предоставили "ri C:\ - r".
In в этом случае, как и другие, я бы вытащил /c из строки $param string и указал его, например:
cmd /c $param
или используйте Invoke-Expression, но используйте с осторожностью. Кстати, когда вы пытаетесь отладить проблемы с отправкой аргументов в EXE из PowerShell, проверьте утилиту echoargs в расширениях сообщества PowerShell (http://pscx.codeplex.com). Это очень удобно:
49> $param = "/c echo foo"
50> echoargs $param
Arg 0 is </c echo foo>
Это показывает, что cmd.exe получает "/ c echo foo " в качестве один
еще один способ сделать это-создать массив аргументов для командной строки и использовать его с оператором apersand & call. Что-то вроде этого:--2-->
$exe = "cmd";
[Array]$params = "/c", "echo", "foo";
& $exe $params;
это хорошо сработало для меня.
Я изначально нашел эту технику здесь: http://techstumbler.blogspot.com/2009/12/windows-commands-with-arguments-in.html
У меня были проблемы с оператором & call в прошлом при попытке вызвать исполняемые команды типа, как вы пытаетесь. Не уверен, что понимаю, почему. Однако Invoke-Expression всегда работает в этом контексте:
PS C:\> $cmd = "cmd /c echo foo"
PS C:\> Invoke-expression $cmd
foo
ваш последний пример, если не удается, потому что " & "обрабатывает строку как один аргумент, поэтому он ищет программу с именем" cmd /c echo foo.исполняемый." :)
это работает:
& $cmd $params
что касается проблемы с двойной кавычкой, кажется, что cmd не нравятся кавычки вокруг аргументов, которые ставит PowerShell. Он получает это:
cmd "/c echo foo"
поэтому я думаю, что он рассматривает все после /c как точную команду, так что:
echo foo"
некоторые программы командной строки и фанковый разбор командной строки (именно поэтому PowerShell берет на себя это задание для функций и командлетов). В случае cmd я бы предложил следующее:
$param = "echo foo"
& cmd /c $param
это артефакт использования cmd / c, я думаю. бег!--2-->
$param = "echo foo"
cmd /c $param
работает нормально. Если у вас нет реального примера кода, немного сложно стрелять в проблемы.
Args обрабатываются по-разному, когда они содержатся в строке:
PS D:\> echo "1 2 3"
1 2 3
PS D:\> echo 1 2 3
1
2
3
те же результаты возникают при использовании переменной для args:
PS D:\> $param = "1 2 3"
PS D:\> echo $param
1 2 3
решение заключается в использовании массива:
PS D:\> $param = @(1,2,3)
PS D:\> echo $param
1
2
3