我希望我的PowerShell脚本可以打印出这样的东西:
Enabling feature XYZ......Done
Write-Output "Enabling feature XYZ......."
Enable-SPFeature...
Write-Output "Done"
但是 Write-Output
总是在结尾打印一个换行符,所以我的输出不在同一行上。有没有办法解决这个问题?
我希望我的PowerShell脚本可以打印出这样的东西:
Enabling feature XYZ......Done
Write-Output "Enabling feature XYZ......."
Enable-SPFeature...
Write-Output "Done"
但是 Write-Output
总是在结尾打印一个换行符,所以我的输出不在同一行上。有没有办法解决这个问题?
Write-Host -NoNewline "正在启用 XYZ 功能......."
Write-Output
,而它的功能与 Write-Host
大不相同,所以被投下了反对票。读者在复制/粘贴答案之前应该注意到这个巨大的差异。 - NathanAldenSrWrite-Host
和 Write-Information
是相同的,可以重定向为输出流 6。因此,您可以将其重定向到文件中,如 6>output.txt
。它没有自己的“思想”,只是您无法从 Unixland 中带来的知识,因此很多人会误解它。 - Naikrovek很不幸的是,正如几个答案和评论中所指出的那样,Write-Host
可能存在危险,并且无法传递到其他进程,而Write-Output
没有-NoNewline
标志。
但这些方法是"*nix"显示进度的方式,而在PowerShell中,显示进度的方法似乎是Write-Progress
:它在PowerShell窗口顶部显示一个带有进度信息的进度条,可从PowerShell 3.0及更高版本中使用,请参阅手册获取详细信息。
# Total time to sleep
$start_sleep = 120
# Time to sleep between each notification
$sleep_iteration = 30
Write-Output ( "Sleeping {0} seconds ... " -f ($start_sleep) )
for ($i=1 ; $i -le ([int]$start_sleep/$sleep_iteration) ; $i++) {
Start-Sleep -Seconds $sleep_iteration
Write-Progress -CurrentOperation ("Sleep {0}s" -f ($start_sleep)) ( " {0}s ..." -f ($i*$sleep_iteration) )
}
Write-Progress -CurrentOperation ("Sleep {0}s" -f ($start_sleep)) -Completed "Done waiting for X to finish"
而且以OP的例子为例:
# For the file log
Write-Output "Enabling feature XYZ"
# For the operator
Write-Progress -CurrentOperation "EnablingFeatureXYZ" ( "Enabling feature XYZ ... " )
Enable-SPFeature...
# For the operator
Write-Progress -CurrentOperation "EnablingFeatureXYZ" ( "Enabling feature XYZ ... Done" )
# For the log file
Write-Output "Feature XYZ enabled"
尽管在您向用户提供信息输出的情况下可能不适用,但可以创建一个字符串来附加输出。 在输出时,只需输出该字符串即可。
当然,在您的情况下,忽略这个示例是愚蠢的,但在概念上非常有用:
$output = "Enabling feature XYZ......."
Enable-SPFeature...
$output += "Done"
Write-Output $output
显示:
Enabling feature XYZ.......Done
Write-Output
仍会产生额外的换行符。这是一个合理的解决方法,但并不是最终解决方案。 - Slogmeister Extraordinaire$output
没有任何区别。 - JLRishe要写入文件,您可以使用字节数组。以下示例创建一个空的ZIP文件,您可以向其中添加文件:
[Byte[]] $zipHeader = 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
[System.IO.File]::WriteAllBytes("C:\My.zip", $zipHeader)
或者使用:
[Byte[]] $text = [System.Text.Encoding]::UTF8.getBytes("Enabling feature XYZ.......")
[System.IO.File]::WriteAllBytes("C:\My.zip", $text)
是的,正如其他答案所述,使用Write-Output无法完成此操作。当PowerShell无法胜任时,请转向.NET。这里甚至有几个.NET答案,但它们比必要的复杂。
只需使用:
[Console]::Write("Enabling feature XYZ.......")
Enable-SPFeature...
Write-Output "Done"
虽然不是最纯粹的PowerShell,但它可以工作。
Write-Host
一模一样,只是人们没想到会这样,所以被踩了。 - JBert在PowerShell中似乎没有办法做到这一点。所有之前的答案都不正确,因为它们的行为方式与Write-Output
不同,更像是Write-Host
,而后者无论如何都没有这个问题。
最接近的解决方案似乎是使用带有-NoNewLine
参数的Write-Host
。通常情况下,您无法将其管道化,但可以通过在Write-Host => Export to a file中描述的方式覆盖此函数,以便轻松地使其接受输出文件的参数。但这仍然远非一个好的解决方案。使用Start-Transcript
可以更好地实现这一点,但该cmdlet在本机应用程序方面存在问题。
Write-Output
在一般情况下无法满足您的需求。
编辑于2023年:
你甚至可以为了疯狂而做出这样的事情:
function log ($msg, [switch] $NoNewLine) { $script:_msg+=$msg; if ($NoNewLine) { Write-Host -NoNewline $msg } else { Write-Host $msg; $script:_msg >>output.txt; $script:_msg = '' } }
测试:
log '启用功能xyx' -NoNewLine; 1..3 | % { sleep 1; log . -NoNewLine }; log '完成'; cat output.txt
启用功能xyx...完成
shufler的回答是正确的。换句话说:不要使用数组形式将值传递给Write-Output,
Write-Output "Parameters are:" $Year $Month $Day
或通过多次调用Write-Output实现等效功能,
Write-Output "Parameters are:"
Write-Output $Year
Write-Output $Month
Write-Output $Day
Write-Output "Done."
首先将您的组件连接到一个字符串变量中:
$msg="Parameters are: $Year $Month $Day"
Write-Output $msg
Write-Output
仍会产生额外的换行符,只是因为它是最后写入的东西,所以你看不见它。这是一个合理的解决方法,但不是一个解决方案。可能有某些内容正在使用无法处理尾随换行符的结果输出。 - Slogmeister Extraordinaire我作弊了,但我相信这是唯一符合所有要求的答案。也就是说,避免了尾部的CRLF,提供了另一个操作在此期间完成的位置,并根据需要正确地重定向到标准输出(stdout)。
$c_sharp_source = @"
using System;
namespace StackOverflow
{
public class ConsoleOut
{
public static void Main(string[] args)
{
Console.Write(args[0]);
}
}
}
"@
$compiler_parameters = New-Object System.CodeDom.Compiler.CompilerParameters
$compiler_parameters.GenerateExecutable = $true
$compiler_parameters.OutputAssembly = "consoleout.exe"
Add-Type -TypeDefinition $c_sharp_source -Language CSharp -CompilerParameters $compiler_parameters
.\consoleout.exe "Enabling feature XYZ......."
Write-Output 'Done.'
pwsh
(powershell core) 中,Add-Type 没有 -CompilerParameters
选项,但你可以使用其他语言来实现相同的功能:python3 -c "import sys; print(sys.argv[1], end='')" "Enabling feature XYZ......."
- Carl Walsh我遇到的问题是,当使用PowerShell v2时,Write-Output实际上会在输出时进行换行,至少是对于stdout而言。我试图将XML文本写入stdout,但没有成功,因为它会在第80个字符处自动换行。
解决方法是使用:
[Console]::Out.Write($myVeryLongXMLTextBlobLine)
在PowerShell v3中,这不是一个问题。Write-Output 在那里似乎正常工作。
根据PowerShell脚本的调用方式,您可能需要使用
[Console]::BufferWidth =< length of string, e.g. 10000)
[System.IO.File]::WriteAllText("c:\temp\myFile.txt", $myContent)