我有一个子进程,我想从 powershell 调用它,该子进程可能是交互式的,或者我可能会直接将数据传输到其中。例如:
# This is interactive:
& c:\python27\python.exe
# This takes redirected input:
echo hi | & c:\python27\python.exe -c "print repr(raw_input())"
我想创建一个函数,用于包装对此类进程的调用。我可以这样做:
function python() {
& c:\python27\python.exe @args
}
# This starts an interactive prompt:
python
# The piped data disappears and the process still reads from the console:
echo hi | python -c "print repr(raw_input())"
或者我可以这样做:
function python() {
$input | & c:\python27\python.exe @args
}
# This doesn't accept interactive input:
python
# The piped data is passed through to the sub-process as intended:
echo hi | python -c "print repr(raw_input())"
我不知道如何编写一个函数来处理这两种情况。如果在没有管道的情况下调用它,我希望它启动一个从 stdin 读取的子进程,如果使用管道输入调用它,我希望它将其输入到子进程的 stdin 中。我可以这样做吗?
答案1
您可以检查$MyInvocation.ExpectingInput
表达式的值以查明您的函数是否期望任何管道输入或它是否是管道的第一个元素。
function python {
if($MyInvocation.ExpectingInput){
$input | & c:\python27\python.exe @args
}else{
& c:\python27\python.exe @args
}
}
答案2
在函数中定义参数,它将保存您的数据。然后检查是否提供了参数并采取相应措施。您可能需要进行一些调整,因为PowerShell 如何将数据传递给外部程序但基本思想依然不变。
准系统示例:
用法:
'foo', '', 'bar' | Invoke-Python
这里我将一个数组传递给Invoke-Python
函数。
结果:
- ‘foo’ 将被传送到 python
- 然后,函数将遇到空参数并调用交互式 Python
- 退出交互式 Python 后,该函数会将“bar”传送到 Python
Invoke-Python
功能:
function Invoke-Python
{
[CmdletBinding()]
Param
(
# This parameter will catch your input data
[Parameter(ValueFromPipeline = $true)]
[string]$InputObject
)
# This block runs when pipeline is initialized.
# It doesn't have access to the parameters,
# they are not yet parsed at this time.
Begin
{
# Set path to the python
$PythonPath = 'c:\python27\python.exe'
}
# This block runs for each pipeline item
Process
{
# Check, is there anything passed in the InputObject parameter
if($InputObject)
{
Write-Host 'We have some data, let''s pipe it into the python'
$InputObject | & $PythonPath @('-c', 'print repr(raw_input())')
}
else
{
Write-Host 'No data, let''s just launch interactive python'
& $PythonPath
}
}
}