Я пытаюсь написать некоторые функции PowerShell, которые выполняют некоторые функции, а затем прозрачно обращаются к существующим встроенным функциям.Я хочу передать все нетронутые аргументы.Я не хочу знать какие-либо подробности аргументов.
Я устал использовать 'splat', чтобы сделать это с @args
, но это не сработало, как я ожидал.
В приведенном ниже примере я написал игрушечную функцию под названием myls
, которая должна печатать hello! и затем вызывать ту же встроенную функцию Get-ChildItem
, что и встроенный псевдоним ls
звонки с остальной частью строки аргумента без изменений.То, что у меня есть, работает довольно хорошо:
function myls
{
Write-Output "hello!"
# $MyInvocation | Format-List # <-- uncomment this line for debug info
Invoke-Expression ("Get-ChildItem " + $MyInvocation.UnboundArguments -join " ")
}
Правильная версия myls
должна быть в состоянии обрабатывать вызовы без аргументов, с одним аргументом, с именованными аргументами, из строки, содержащей несколько полу-colon с разделителями, и с переменными в аргументах, включая строковые переменные, содержащие пробелы.По сути, это должна быть альтернатива ls
.
. В приведенных ниже тестах сравниваются myls
и встроенный ls
:
[ПРИМЕЧАНИЕ: выходной сигнал элидируется и/ или сжато для экономии места]
PS> md C:\p\d\x, C:\p\d\y, C:\p\d\"jay z"
PS> cd C:\p\d
PS> ls # no args
PS> myls # pass
PS> cd ..
PS> ls d # one arg
PS> myls d # pass
PS> $a="A"; $z="Z"; $y="y"; $jz="jay z"
PS> $a; ls d; $z # multiple statements
PS> $a; myls d; $z # pass
PS> $a; ls d -Exclude x; $z # named args
PS> $a; myls d -Exclude x; $z # pass
PS> $a; ls d -Exclude $y; $z # variables in arg-line
PS> $a; myls d -Exclude $y; $z # pass
PS> $a; ls d -Exclude $jz; $z # variables containing spaces in arg-line
PS> $a; myls d -Exclude $jz; $z # FAIL!
Есть ли способ, которым я могу переписать myls
, чтобы получить желаемое поведение?
Краткий ответ: Да, это возможно.Плохая новость: требуется код, который знает детали параметров и другие метаданные о функции, к которой вы хотите обратиться.Хорошая новость: не нужно писать все это самостоятельно .Эти метаданные доступны программно, и существуют доступные модули, которые можно использовать для автоматической генерации скелетного прокси-кода (см. Ответ @ Jaykul ниже).Я решил использовать модуль с именем "MetaProgramming" .После импорта генерация выпадающего скрипта myls
очень проста:
New-ProxyCommand ls > .\myls.ps1
Затем можно начать настройку только что сгенерированного скрипта myls.ps1
, например:
...
begin
{
Write-Output "hello!" # <-- add this line
try {
$outBuffer = $null
...
Вуаля!Эта новая версия проходит все тесты.