Если у меня есть функция, которая принимает более одного строкового параметра, первый параметр, кажется, получает все назначенные ему данные, а остальные параметры передаются как пустые.
Скрипт быстрого теста:
Function Test([string]$arg1, [string]$arg2)
{
Write-Host "`$arg1 value: $arg1"
Write-Host "`$arg2 value: $arg2"
}
Test("ABC", "DEF")
Сгенерированный вывод
$arg1 value: ABC DEF
$arg2 value:
Правильный вывод должен быть:
$arg1 value: ABC
$arg2 value: DEF
Кажется, это согласуется между v1 и v2 на нескольких машинах, поэтому, очевидно, я делаю что-то не так. Кто-нибудь может указать, что именно?
powershell
Насир
источник
источник
Test "ABC" "DEF"
Ответы:
Параметры в вызовах функций в PowerShell (все версии) разделяются пробелом, а не запятыми . Кроме того, круглые скобки совершенно не нужны и вызовут ошибку разбора в PowerShell 2.0 (или более поздней версии), если
Set-StrictMode
он активен. Аргументы в скобках используются только в методах .NET.источник
(1,2,3)
в функцию фактически рассматривается как массив; один аргумент. Если вы хотите использовать аргументы стиля метода OO, используйте модули:$m = new-module -ascustomobject { function Add($x,$y) { $x + $y } }; $m.Add(1,1)
Powershell
является языком оболочки, и для языков оболочки характерно использование пробелов в качестве разделителя токенов. Я бы не сказал ,Powershell
в настоящее время здесь по- другому, это право в соответствии с другими оболочками системы по умолчанию , какcmd
,sh
,bash
и т.д.Правильный ответ уже был предоставлен, но эта проблема кажется достаточно распространенной, чтобы дать некоторые дополнительные сведения для тех, кто хочет понять тонкости.
Я бы добавил это просто как комментарий, но я хотел бы добавить иллюстрацию - я сорвал это с моей быстрой справочной таблицы по функциям PowerShell. Это предполагает, что подпись функции f
f($a, $b, $c)
:Таким образом, можно вызывать функцию с позиционными параметрами, разделенными пробелами, или независимыми от порядка именованными параметрами. Другие подводные камни показывают, что вам необходимо знать запятые, скобки и пробелы.
Для дальнейшего чтения см. Мою статью « Вниз по кроличьей норе: изучение конвейеров, функций и параметров PowerShell» . Статья содержит ссылку на краткий справочник / настенную диаграмму.
источник
Здесь есть несколько хороших ответов, но я хотел бы отметить несколько других вещей. Параметры функций - это место, где светит PowerShell. Например, вы можете иметь именованные или позиционные параметры в расширенных функциях, например:
Затем вы можете либо вызвать его, указав имя параметра, либо просто использовать позиционные параметры, поскольку вы явно их определили. Так что любой из них будет работать:
Первый пример работает, хотя
Name
предоставляется второй, потому что мы явно использовали имя параметра. Второй пример работает в зависимости от позиции, поэтомуName
должен быть первым. Когда это возможно, я всегда стараюсь определить позиции, чтобы оба варианта были доступны.PowerShell также имеет возможность определять наборы параметров. Это использует это вместо перегрузки метода, и снова довольно полезно:
Теперь функция будет либо принимать имя, либо идентификатор, но не оба. Вы можете использовать их по месту или по имени. Так как они другого типа, PowerShell поймет это. Так что все это будет работать:
Вы также можете назначить дополнительные параметры для различных наборов параметров. (Это был довольно простой пример.) Внутри функции вы можете определить, какой набор параметров использовался с помощью свойства $ PsCmdlet.ParameterSetName. Например:
Затем, на смежном примечании, есть также проверка параметров в PowerShell. Это одна из моих любимых функций PowerShell, и она делает код внутри ваших функций очень чистым. Есть множество проверок, которые вы можете использовать. Несколько примеров:
В первом примере ValidatePattern принимает регулярное выражение, которое гарантирует, что предоставленный параметр соответствует ожидаемому. Если это не так, выдается интуитивно понятное исключение, которое говорит вам, что именно не так. Таким образом, в этом примере «Something» будет работать нормально, но «Summer» не пройдет проверку.
ValidateRange гарантирует, что значение параметра находится в диапазоне, который вы ожидаете для целого числа. Таким образом, 10 или 99 сработают, но 101 сгенерирует исключение.
Еще одним полезным является ValidateSet, который позволяет явно определять массив допустимых значений. Если будет введено что-то еще, будет сгенерировано исключение. Есть и другие, но, вероятно, наиболее полезным является ValidateScript. Для этого требуется блок скрипта, который должен иметь значение $ true, поэтому пределом является небо. Например:
В этом примере мы уверены, что не только $ Path существует, но и что это файл (в отличие от каталога) и имеет расширение .csv. ($ _ относится к параметру, находящемуся внутри вашего скриптового блока.) Вы также можете передать гораздо большие многострочные скриптовые блоки, если требуется этот уровень, или использовать несколько скриптовых блоков, как я сделал здесь. Это чрезвычайно полезно и делает для хороших чистых функций и интуитивных исключений.
источник
My_Function -NamedParamater "ParamValue"
стиля вызова функции. Это шаблон, которому должен следовать код PS-сценария для удобства чтения.Вы вызываете функции PowerShell без скобок и без использования запятой в качестве разделителя. Попробуйте использовать:
В PowerShell запятая (,) является оператором массива, например
Устанавливается
$a
в массив с тремя значениями.источник
источник
Если вы разработчик на C # / Java / C ++ / Ruby / Python / Pick-A-Language-From-This-Century и хотите вызывать свою функцию с запятыми, потому что это то, что вы всегда делали, тогда вам нужно что-то нравится:
Теперь позвоните:
и вы увидите
источник
Если вы не знаете (или не заботитесь), сколько аргументов вы будете передавать функции, вы также можете использовать очень простой подход, например;
Код :
Это распечатало бы все аргументы. Например:
Вывод
Я считаю это особенно полезным при создании функций, которые используют внешние команды, которые могут иметь много разных (и необязательных) параметров, но полагаются на указанную команду для обеспечения обратной связи по синтаксическим ошибкам и т. Д.
Вот еще один пример из реальной жизни (создание функции для команды tracert, которую я ненавижу запоминать усеченное имя);
Код :
источник
Если вы пытаетесь:
ты получаешь:
Итак, вы видите, что скобки разделяют параметры
Если вы пытаетесь:
ты получаешь:
Теперь вы можете найти некоторую непосредственную полезность скобок - пробел не станет разделителем для следующего параметра - вместо этого у вас есть функция eval.
источник
@
) перед ведущим Paren, как этот пустой массив:@()
; или этот массив с двумя числами:@(1, 2)
.Поскольку это часто рассматривается вопрос, я хочу отметить , что функция PowerShell следует использовать утвержденные глаголы ( Verb существительного в качестве имени функции). Глагольная часть имени определяет действие, которое выполняет командлет. Существительная часть имени идентифицирует сущность, над которой выполняется действие. Это правило упрощает использование ваших командлетов для опытных пользователей PowerShell.
Кроме того, вы можете указать, например, является ли параметр обязательным и положение параметра:
Для передачи параметра в функцию вы можете использовать позицию :
Или вы указываете имя параметра :
Вы не используете круглые скобки, как при вызове функции в C #.
Я бы рекомендовал всегда передавать имена параметров при использовании более одного параметра, так как это более читабельно .
источник
Get-Node
командлет. Для нас было бы ясно, что мы должны ссылатьсяGet-Node
, ниRetrieve-Node
, ниReceive-Node
, ни .....Я не знаю, что вы делаете с функцией, но посмотрите на использование ключевого слова «param». Он немного более мощный для передачи параметров в функцию и делает его более удобным для пользователя. Ниже приведена ссылка на слишком сложную статью Microsoft об этом. Это не так сложно, как статья озвучивает.
Использование Param
Также вот пример из вопроса на этом сайте:
Проверьте это.
источник
источник
Я заявил следующее ранее:
Общая проблема заключается в использовании формы единственного числа
$arg
, которая является неправильной. Это всегда должно быть во множественном числе$args
.Проблема не в этом. На самом деле
$arg
может быть все что угодно. Проблема заключалась в использовании запятой и скобок.Я запускаю следующий код, который работал, и вывод следующий:
Код:
Тест "Азбука" "DEF"
Вывод:
источник
Это правильное
params
заявление.Смотрите about_Functions_Advanced_Parameters .
И это действительно работает.
источник
Вы также можете передать параметры в функцию, подобную этой:
источник
Я не вижу здесь упомянутого, но разбрызгивание ваших аргументов является полезной альтернативой и становится особенно полезным, если вы строите аргументы команды динамически (в отличие от использования
Invoke-Expression
). Вы можете использовать массивы для позиционных аргументов и хеш-таблицы для именованных аргументов. Вот некоторые примеры:Сплат с массивами (позиционные аргументы)
Тест-соединение с позиционными аргументами
С массивом Splatting
Splat With Hashtable (именованные аргументы)
Тест-соединение с именованными аргументами
С хэштабличным
Сплат позиционные и именованные аргументы одновременно
Тест-соединение с позиционными и именованными аргументами
Splatting Array и Hashtables вместе
источник