2016-11-04 2 views
3

Делает ли PowerShell какое-то ближайшее совпадение или автозаполнение при работе с аргументами, переданными скрипту? Учитывая этот код ...Соответствие скрипту Аргумент

[CmdletBinding()] 
Param(
    [string][Alias("aS")] $applySet, 
    [string][Alias("cS")] $conformSet, 

    [string][Alias("sL")] $setList, 
    [Parameter(ValueFromRemainingArguments = $true)][Object[]]$extraParameters = @() 
) 

Write-Host "s: $set" 
Write-Host "sL: $setList" 
Write-Host "aS: $applySet" 
Write-Host "cS: $conformSet" 
Write-Host "X: $extraParameters" 

Если я использую -junk «вредную» в ярлыке сценария я получаю эту информацию в $extraParameters, как ожидалось. Пропуская что-то, скажем -aplySet, также отображается как дополнительный параметр. Однако использование -set фактически заполняет переменную $setList, а не $extraParameters, как и следовало ожидать.

Проверено в PowerShell 2.0 и 5.1. Есть предположения?

ответ

2

PowerShell позволяет использовать начальные символы имени параметра, если они недвусмысленны.

+0

Хм, я «угадать», что имеет смысл. По крайней мере, на языке сценариев. Желаю, чтобы его можно было отключить, как хотелось бы, что конвейерный выход может быть. По крайней мере, с аргументами командной строки. Но на данный момент я предполагаю, что мне нужно документировать поведение для людей и перестать пытаться поймать определенные ошибки, которые PS действительно не являются ошибками. – Gordon

+1

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

+0

Точно. И я хочу поймать каждое «неуместное» использование. Но это, кажется, обходит это, поскольку я не могу правильно уловить -set как ошибку, потому что PowerShell автоматически принимает значение -setlist. И мы все знаем о том, чтобы предположить. ;) – Gordon

2

Это несколько недокументированных, насколько я могу судить.

  • about_Parameters не упоминает использование сокращенных параметров.
  • about_Command_Syntax рассказывает об использовании параметров, но не в коротких версиях.
  • I Save-Help 'd вся помощь и grep sls'd это для вероятных терминов, ничего не видел.
  • This blog post from 2006 переговоров об этом, так что это было в PowerShell, начиная с версией 1,0

В PowerShell 1.0, часть логики разрешения имен параметров включает в себя поддержку для определения параметров по кратчайшей подстроке, который однозначно идентифицирует параметр или псевдоним для параметра по сравнению со списком параметров и псевдонимов для командлета.

и упоминается в книге разработчик PowerShell Брюс Пейет в «PowerShell в действии», глава 2, P.39-40:

Кусок интерпретатора PowerShell, что цифры все это из называется параметр связующего. Связывание параметров является умным - для него не требуется указать полное имя параметра, если вы укажете достаточно, чтобы он однозначно различал то, что вы имеете в виду.

Но это все, без комментариев о выборе дизайна или обосновании, которое я могу видеть. Представляя, как комментирует @Mike Shepard, двойная роль PowerShell в качестве интерактивной оболочки (где люди хотят печатать как можно меньше и пишут одноразовые команды throwaway) и язык сценариев (где люди хотят ясности, удобочитаемости, ремонтопригодности несколькими люди в течение более длительного времени) является тем, что порождает короткие версии/длинные версии всего.Псевдонимы

gci -r | sls (date) 
Get-ChildItem -Recurse | Select-String -Pattern (Get-Date) 
  • Позиционные привязки параметров, без имени параметра
  • Имени параметра аббревиатура
  • Параметра объекта свойства Automagic связывания
  • разрешения Command может поиск Get- командлетов, если Get- остается не включенные в другие категории

FWIW, это, кажется, this line in the source code из System.Management.Automation/engine/MergedCommandParameterMetadat.cs, что кто-то на Слэка PowerShell идентифицированного, который фактически делает матч параметра:

foreach (string parameterName in _bindableParameters.Keys) 
{ 
// --- 
    if (CultureInfo.InvariantCulture.CompareInfo.IsPrefix(parameterName, name, CompareOptions.IgnoreCase)) 
// --- 
    { 
     // If it is an exact match then only return the exact match 
     // as the result 

     if (tryExactMatching && String.Equals(parameterName, name, StringComparison.OrdinalIgnoreCase)) 
     { 
      return _bindableParameters[parameterName]; 
     } 
     else 
     { 
      matchingParameters.Add(_bindableParameters[parameterName]); 
     } 
    } 
} 
+2

Великий слежки. Чтобы дать философии имя: _elastic syntax_: «PowerShell поддерживает гибкий синтаксис-сжатие в командной строке и завершается скриптами». «Раньше мы говорили, что вам просто нужно указать имя параметра, чтобы отличить его от других параметров команды». Из предстоящего третьего издания «PowerShell in Action» (первая глава доступна бесплатно) - https://www.manning.com/books/windows-powershell-in-action-third-edition – mklement0