Правильные значения параметров не переданы в функцию - PullRequest
2 голосов
/ 18 марта 2019

У меня есть файл с именем TestFunc.ps1.Его содержимое выглядит следующим образом:

Function TestFunc([string]$param1, [string]$param2)
{
    Write-Host "------------------"
    Write-Host $param1
    Write-Host $param2
    Write-Host "------------------"
}

TestFunc $param1 $param2 

Я назвал его следующим образом

C:\Test\TestFunc.ps1 "Hello" "World"

Вывод выглядит следующим образом

------------------


------------------

Я ожидаю вывод как

------------------
Hello 
World 
------------------

Что я здесь не так делаю?

Ответы [ 2 ]

5 голосов
/ 18 марта 2019

Параметры определены для области действия функции, а не для скрипта.

То, что вы хотите, это Параметр раздел:

param ([string]$param1, [string]$param2)

function TestFunc([string]$param1, [string]$param2) {
    Write-Host "------------------"
    Write-Host $param1
    Write-Host $param2
    Write-Host "------------------"
}
TestFunc $param1 $param2 

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

param ([string]$param1, [string]$param2)

Write-Host "------------------"
Write-Host $param1
Write-Host $param2
Write-Host "------------------"

Или, альтернативно:

param ([string]$param1, [string]$param2)

function TestFunc {
    Write-Host "------------------"
    Write-Host $param1
    Write-Host $param2
    Write-Host "------------------"
}
TestFunc

Или используйте автоматическую переменную $args без определения каких-либо параметров:

function TestFunc {
    Write-Host "------------------"
    Write-Host $args[0]
    Write-Host $args[1]
    Write-Host "------------------"
}
TestFunc foo bar
1 голос
/ 19 марта 2019

К дополнение полезный и эффективный ответ Марса :

PowerShell имеет две в значительной степени эквивалентные синтаксические формы для определения параметров - оставляя определения PSv5 + class в стороне [1] :

Примечание. Для краткости списки параметров размещаются на одной строке ниже;однако обе синтаксические формы позволяют размещать отдельные параметры в отдельной строке.

  • Только для функций :

    • C / C # -подобно: a , разделенный список объявлений переменных параметров внутри (...) после функции имя и перед открытием {;Например:

      function foo ($bar, $baz) {
        # ... 
      }
      
  • Для скриптов и функций тоже , а также блоки сценариев ({ ... }, которые похожи на анонимные функции):

    • Специфично для PowerShell: A , разделенный список объявлений переменных параметров внутри param(...), который должен быть первым оператором внутри body (кроме комментариев и using директив):

      # --- Script foo.ps1
      param($bar, $baz)
      
      # ...
      
      
      # --- Function
      # This example is fully equivalent to `foo ($bar, $baz) { ...` above.
      # Note that no () is needed after the function name.
      function foo {
        param($bar, $baz)
        # ...
      }
      
      # --- Script block
      & {
        param($bar, $baz)
        # ...
      } # arguments...
      

Для краткости, следующие дополнительные элементы были опущены выше:

  • В отдельных объявлениях параметров :

    • Набор текста ;например, чтобы объявить параметр $foo как тип [int] (System.Int32):

      • [int] $foo
    • Параметратрибуты , обычно, но не исключительно через атрибут [Parameter()];среди прочего, последний определяет, является ли связанный параметр обязательным ;Например:

      • [Parameter(Mandatory=$true)] [int] $foo
  • Над оператором param(...) * только 1133 * :

    • Атрибут [CmdletBinding()], который делает функцию или сценарий продвинутым , с поведением наравне с (скомпилированным) PowerShell командлетами - см. about_Functions_Advanced

В простых (не продвинутых) скриптах и ​​функциях это также опция вообще не объявлять параметры , в которых любые передаваемые аргументы содержатся в автоматической $args переменной , которая является обычным массивом PowerShell([object[]]).
Вы даже можете объединить $args с объявленными параметрами: $args затем содержит только те аргументы, которые не привязаны к объявленным.

Byнапротив, в продвинутых сценариях и функциях вам в основном разрешено передавать только аргументы, которые связываются с объявленными параметрами.


Когда выбирать, какую синтаксическую форму:

  • Файлы сценариев и блоки сценариев must используйте оператор param(...) - синтаксис, подобный C #, недоступен.

  • Функции могут технически использовать C #-подобный синтаксис и param(...) взаимозаменяемо , , за исключением , если требуется атрибут [CmdletBinding()], и в этом случае работает только синтаксис param(...).

    • Тем не менее, для согласованности и простоты расширяемости (делая функцию расширенной позже), синтаксис param(...) обычно предпочтительнее .

    • Кроме того, использование C # -подобного синтаксиса часто может более легко привести к путанице синтаксиса , когда вызывает функцию , учитывая, что командлеты и функции PowerShell вызываются как команды оболочки (без скобок, аргументы, разделенные пробелами), не такие как C # методы ;например,
      foo 1 2 (или foo -bar 1 -baz 2) вместо foo(1, 2)


[1] Объявления методов в class определениях должны использовать C # -подобный синтаксис, и атрибуты параметров не поддерживаются (они поддерживаются только в свойства ).Точно так же, как методы в нативных типах .NET, методы класса также должны быть вызваны с синтаксисом метода - см. этот ответ и раздел справки about_Classes .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...