У меня есть этот фрагмент ps:
function myFuncWithArgs($arg) {
Write-Output $arg
}
$temp = 'sometext'
$cFunc = 'myFuncWithArgs'
& $cFunc $temp
это работает, но мне нужно, чтобы $temp находился в той же строке, что и $cFunc, и работал так же. Это не работает:
$cFunc = 'myFuncWithArgs' $temp
& $cFunc
возможно ли это в pshell?
Не уверен, что я действительно понимаю, что вы делаете, но, возможно, попробуйте удалить кавычки. $cFunc = myFuncWithArgs $temp
Похоже, вы пытаетесь сохранить полную команду (исполняемый файл + аргументы) в переменной для последующего выполнения по запросу.
Используйте для этого блок скрипта ({ ... }
), который вы можете вызвать по запросу с помощью &
, оператора вызова:
# Define the full command as a script block.
$scriptBlock = { myFuncWithArgs $temp }
# Invoke it.
# You may also pass arguments to it, but that only makes sense
# if it is designed to accept them, e.g. via $args
& $scriptBlock
Примечание:
&
не работает со строкой, содержащей полную команду. Его аргумент должен быть либо блоком скрипта, как показано, либо именем команды, либо путем к исполняемому файлу, а любые аргументы для передачи этому блоку скрипта/команде/исполняемому файлу должны быть указаны отдельно, например & { Write-Output $args } arg1 ...
или & $pathToExecutable arg1 ...
В приведенном выше примере используется литерал блока сценария. Чтобы создать блок скрипта из строки, используйте [scriptblock]::Create():
# IMPORTANT:
# Be sure that you either fully control or implicitly trust
# the content of this string, so as to prevent execution of unwanted code.
$commandString = 'myFuncWithArgs $temp'
$scriptBlock = [scriptblock]::Create($commandString)
& $scriptBlock
Вы упоминаете Read-Host, то есть запрашиваете у пользователя, как источник вашей командной строки, и в этом случае оговорка в разделе «ВАЖНО:» выше определенно применяется.
Если риск выполнения произвольных введенных пользователем команд приемлем для вас, вы можете просто использовать Invoke-Expression $commandString
, но обратите внимание, что Invoke-Expression
обычно не рекомендуется именно из-за его способности выполнять произвольный код, хранящийся в строке.
Однако есть золотая середина, которая требует [scriptblock]::Create()
:
Restricted
языковом режиме, с возможностью настройки того, какие конкретные команды и переменные разрешены.это работает: $scriptBlock = {myFuncWithArgs 'some text'} & $scriptBlock
но если я попытаюсь использовать Read-Host -prompt и вставить в консоль {myFuncWithArgs 'some text'}
, то я получаю сообщение об ошибке: & : The term '{myFuncWithArgs 'some text'}' is not recognized as the name of a cmdlet, function, script file, or operable program.
Я использую Read-Host для прослушивания данных из родительского сценария NodeJS. Скрипт NodeJS отлично работает с отдельными функциями: spawnedChild.stdin.write("functionNOArgs\r");
, но я все еще не могу заставить его работать с аргументами: spawnedChild.stdin.write("functionWithArgs\r 'R:/file.txt'");
. Я должен был начать тему, включив эту информацию, но я посчитал, что просто испортил синтаксис или какую-то другую незначительную проблему.
наконец, это работает! При написании функции и аргумента нет необходимости в \r после функции, поэтому: spawnedChild.stdin.write("functionWithArgs 'R:/file.txt'");
с [scriptblock]::Create
= решение, спасибо!
Рад это слышать, @bitbar. Действительно, \r
не следует использовать, потому что PowerShell ожидает, что заданные команды будут либо в одной строке, либо использовать явное продолжение строки с помощью `
(исключение составляет случай, когда команда синтаксически неполная, и в этом случае PowerShell также просматривает следующую строку). , например, при размещении |
в конце строки).
Вы можете присваивать значение сразу нескольким переменным, таким образом сохраняя все в одной строке:
$cFunc,$cArgs = 'myFuncWithArgs',$temp
& $cFunc @cArgs
Вызывайте функцию без скобок, а параметры без запятых и с пробелами.
function Dartagnan($a, $b)
{
$c = $a + $b;
Write-Host $c;
#result is 12;
}
Dartagnan 5 7;
Read-Host;
Что должно быть
$cFunc
, потому что сейчас у вас есть синтаксическая ошибка. Это должна быть строка или массив?