Start-Process访问StandardError和StandardOutput属性时,PowerShell 命令中是否存在错误?
如果我运行以下命令,我得不到输出:
$process = Start-Process -FilePath ping -ArgumentList localhost -NoNewWindow -PassThru -Wait
$process.StandardOutput
$process.StandardError
Run Code Online (Sandbox Code Playgroud)
但是,如果我将输出重定向到文件,我得到预期的结果:
$process = Start-Process -FilePath ping -ArgumentList localhost -NoNewWindow -PassThru -Wait -RedirectStandardOutput stdout.txt -RedirectStandardError stderr.txt
Run Code Online (Sandbox Code Playgroud) 为什么PowerShell在下面的第二个例子中显示出令人惊讶的行为?
首先,一个理智行为的例子:
PS C:\> & cmd /c "echo Hello from standard error 1>&2"; echo "`$LastExitCode=$LastExitCode and `$?=$?"
Hello from standard error
$LastExitCode=0 and $?=True
Run Code Online (Sandbox Code Playgroud)
没有惊喜.我打印一条消息到标准错误(使用cmd's echo).我检查变量$?和$LastExitCode.正如预期的那样,它们分别等于True和0.
但是,如果我要求PowerShell通过第一个命令将标准错误重定向到标准输出,我会得到一个NativeCommandError:
PS C:\> & cmd /c "echo Hello from standard error 1>&2" 2>&1; echo "`$LastExitCode=$LastExitCode and `$?=$?"
cmd.exe : Hello from standard error
At line:1 char:4
+ cmd <<<< /c "echo Hello from standard error 1>&2" 2>&1; echo "`$LastExitCode=$LastExitCode and `$?=$?"
+ CategoryInfo : NotSpecified: (Hello from …Run Code Online (Sandbox Code Playgroud) 我想从PowerShell启动一个Java程序,并在控制台上打印结果.
我已按照此问题的说明操作: 使用Start-Process捕获标准输出和错误
但对我来说,这不符合我的预期.我做错了什么?
这是脚本:
$psi = New-object System.Diagnostics.ProcessStartInfo
$psi.CreateNoWindow = $true
$psi.UseShellExecute = $false
$psi.RedirectStandardOutput = $true
$psi.RedirectStandardError = $true
$psi.FileName = 'java.exe'
$psi.Arguments = @("-jar","tools\compiler.jar","--compilation_level", "ADVANCED_OPTIMIZATIONS", "--js", $BuildFile, "--js_output_file", $BuildMinFile)
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $psi
$process.Start() | Out-Null
$process.WaitForExit()
$output = $process.StandardOutput.ReadToEnd()
$output
Run Code Online (Sandbox Code Playgroud)
该$output变量总是空的(并且没有打印过程的控制台上).
我想将PowerShell命令的stderr输出存储在变量中.我不想将它存储在一个文件中,我不希望包含标准输出,只是错误输出.
这会重定向到名为的文件error.txt:
&$ command $ params 2> error.txt
这会将stderr和stdout重定向到$ output变量:
$ output =&$ command $ params 2>&1
但我想只将错误输出存储在一个变量中(与上面的error.txt文件的内容相同),而不是将任何内容写入文件.我怎么做?
在PowerShell脚本中,我所说的计划,并希望重定向stdout和stderr到不同的文件,同时还显示两者在控制台输出。所以基本上,我想要
stdout -> stdout
stdout -> out.log
stderr -> stderr
stderr -> err.log
Run Code Online (Sandbox Code Playgroud)
到目前为止,我想出了这个代码,但不幸的是它只满足要求 1、2 和 4。Stderr 没有打印在屏幕上。
& program 2>"err.log" | Tee-Object -FilePath "out.log" -Append | Write-Host
Run Code Online (Sandbox Code Playgroud)
我怎样才能打印stderr到控制台?由于写入 tostderr产生红色字体,我不想重定向stderr到stdout,因为那样我会失去错误的视觉印象。
我试图弄清楚如何确定使用 Invoke-Expression 抛出的命令是否失败。甚至变量 $?、$LASTEXITCODE 或 -ErrorVariable 也帮不了我。
例如 :
PS C:\> $cmd="cat c:\xxx.txt"
使用 Invoke-Expression 调用 $cmd
PS C:\> Invoke-Expression $cmd -ErrorVariable err
Get-Content : Cannot find path 'C:\xxx.txt' because it does not exist.
At line:1 char:4
+ cat <<<< c:\xxx.txt
+ CategoryInfo : ObjectNotFound: (C:\xxx.txt:String) [Get-Content], ItemNotFoundExcep
tion
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
美元?是真的
PS C:\> $?
True
$LASTEXITCODE 为 0
PS C:\> $LASTEXITCODE
0
而 $err 是空的
PS C:\> $err
PS C:\>
我发现的唯一方法是在文件中重定向 STD_ERR 并测试该文件是否为空
PS C:\> Invoke-Expression $cmd …
我想调用任意表达式并将 std 错误重定向到变量而不重定向到文件。
例如,在 Powershell 中,可以使用 2> 运算符重定向标准错误。使用临时文件,我可以轻松获得我想要的内容:
#$expr = "1/0" # with std error
#$expr = "2+2" # without stderror
#$expr = "Get-Service invalidsvc" # with stderror
$expr = "try { throw '111' } catch { }" # without std error
$ans = Invoke-Expression $expr -ErrorVariable ev 2> C:\log\stderr.txt
if(cat C:\log\stderr){
Write-Host "Error $ev"
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能做同样的事情,但不创建临时输出文件?
错误的解决方案:
使用 -ErrorVariable 开关。反例:
Invoke-Expression $expr -ErrorVariable ev 2> C:\aaa\file1.txt $expr = "try { throw '111' } catch { }" Write-Host …