Почему наклон я выполняю commandlet с аргументами от строки в powershell?

Нет действительно ничего неправильно с этим, это - просто вопрос того, называете ли Вы это модульным тестом или интеграционным тестом. Просто необходимо удостовериться, что, если Вы действительно взаимодействуете с файловой системой, нет никаких непреднамеренных побочных эффектов. А именно, удостоверьтесь, что Вы моетесь после себя - удаляют любые временные файлы, которые Вы создали - и что Вы случайно не перезаписываете существующий файл, который, оказалось, имел то же имя файла как временный файл, который Вы использовали. Всегда используйте относительные пути и не полные пути.

Это также была бы хорошая идея chdir() во временный каталог прежде, чем запустить Ваш тест, и chdir() назад впоследствии.

6
задан George Mauer 15 August 2009 в 18:04
поделиться

3 ответа

Из справки (about_Operators):

&  Call operator
  Description: Runs a command, script, or script block. Because the call
  operator does not parse, it cannot interpret command parameters.

Вы можете использовать блок скрипта вместо строки:

$s = { mv sa.csproj sb.csproj }
& $s

Или вы можете использовать Invoke-Expression :

Invoke-Expression $str

] или

iex $str

В отличие от & , Invoke-Expression анализирует содержимое строки, поэтому вы можете поместить туда что угодно, а не только одну команду.

]
11
ответ дан 8 December 2019 в 13:01
поделиться

Все предложения Йоханнеса верны, но я хочу сообщить людям, что в версии 2 есть еще один вариант. Вы помещаете команду в строку, как и раньше, но вы помещаете параметры в хеш-таблицу и вызываете ее с помощью &, например:

$cmd = 'mv'
$params = @{Path = 'log.txt'; Destination = 'log.bak'}
&$cmd @params

Здесь используется новая функция V2, называемая splatting. Это похоже на использование файла ответов для команды, но вы помещаете параметры в хеш-таблицу вместо файла.

Примечание: вы также можете поместить параметры в массив, который будет включать параметры «по позициям», а не по имени, например:

$cmd = "cpi"
$params = ('log.txt', 'log.bak')
&$cmd @params

Это может не совсем соответствовать проблеме OP, но это уловка, о которой стоит знать.

5
ответ дан 8 December 2019 в 13:01
поделиться

Некоторое время назад мне пришлось ответить на аналогичный вопрос о вызове внешней программы после создания списка аргументов:

Проверено, похоже, используется . $ program $ argString или & $ program $ argString не работает, если $ argString содержит несколько аргументов. . операторы и & просто выполняют прямой вызов, передавая весь $ argString как один аргумент.

Вместо использования [string] $ argString и выполнения $ argString + = "-aaa` "bbb`" ", вы можете изменить его на [string [ ]] $ argArray и используйте $ argArray + = @ ('- aaa', 'bb b') , который будет работать и при необходимости автоматически экранирует строки.

Вы также можете использовать $ process = [Diagnostics.Process] :: Start ($ program, $ argString) . Это упростит отслеживание хода выполнения, но сложнее получить какой-либо текстовый вывод.

Или вы можете поместить все в строку и использовать Invoke-Expression "$ program $ argString" , который проанализирует всю строку как команду и выполнит ее правильно.

Как Кейт упомянул, что сплаттинг - еще один хороший вариант в PowerShell 2.

2
ответ дан 8 December 2019 в 13:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: