Answers:
写主机-NoNewline“启用功能XYZ......。”
Write-Output
,因此遭到拒绝Write-Host
。读者在复制/粘贴答案之前应注意这一巨大差异。
Write-Host
几乎永远不是正确的答案。这相当于>/dev/tty
在Unixland中进行。
Write-Progress
在某些情况下可能是合适的,请参见下面的示例。
Write-Output
。Write-Output
没有-NoNewLine
参数。
不幸的是,正如在一些答案和评论中指出的那样,这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
。合理的解决方法,但不是解决方案。
要写入文件,可以使用字节数组。以下示例创建一个空的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)
简化FrinkTheBrave的响应:
[System.IO.File]::WriteAllText("c:\temp\myFile.txt", $myContent)
我遇到的问题是,在使用PowerShell v2时,Write-Output实际上使输出换行,至少是对stdout而言。我试图将XML文本写到stdout失败,因为它很难用字符80包裹。
解决方法是使用
[Console]::Out.Write($myVeryLongXMLTextBlobLine)
在PowerShell v3中,这不是问题。写输出似乎在那里正常工作。
根据PowerShell脚本的调用方式,您可能需要使用
[Console]::BufferWidth =< length of string, e.g. 10000)
在写到stdout之前。
在PowerShell中似乎无法执行此操作。前面的所有答案都不正确,因为它们的行为方式与Write-Output
行为方式不同,但更像Write-Host
是没有问题的。
关闭解决方案似乎Write-Host
与-NoNewLine
参数一起使用。您不能通过管道传输这通常是一个问题,但是有一种方法可以覆盖此功能,如Write-Host => Export to a file中所述,因此您可以轻松地使其接受输出文件的参数。这仍然不是一个好的解决方案。有了Start-Transcript
这更是可用的,但该cmdlet与本地应用程序的问题。
Write-Output
在一般情况下根本无法满足您的需求。
Write-Host
这是可怕的世界破坏者,但是您可以使用它仅向用户显示进度,同时使用它Write-Output
进行日志记录(而不是OP要求进行日志记录)。
Write-Output "Enabling feature XYZ" | Out-File "log.txt" # Pipe to log file
Write-Host -NoNewLine "Enabling feature XYZ......."
$result = Enable-SPFeature
$result | Out-File "log.txt"
# You could try{}catch{} an exception on Enable-SPFeature depending on what it's doing
if ($result -ne $null) {
Write-Host "complete"
} else {
Write-Host "failed"
}
Write-Progress
。
您根本无法使PowerShell省略那些讨厌的换行符...没有脚本或cmdlet可以。当然,Write-Host绝对是胡说八道,因为您无法从中重定向/管道传输!
不过,您可以编写自己的EXE文件来执行此操作,这就是我在“堆栈溢出”问题中说明的操作方法(如何在PowerShell中输出内容)。
shufler的答案是正确的。换句话说:不是使用ARRAY FORM将值传递到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."
首先将您的组件串联成一个STRING VARIABLE:
$msg="Parameters are: $Year $Month $Day"
Write-Output $msg
这将防止由于多次调用Write-Output(或ARRAY FORM)而导致的中间CRLF,但当然不会抑制Write-Output Commandlet的最终CRLF。为此,您将必须编写自己的Commandlet,使用此处列出的其他复杂解决方法之一,或者等到Microsoft决定支持-NoNewline
Write-Output选项。
您希望向控制台提供文本进度表(即“ ....”),而不是写入日志文件,也可以通过使用Write-Host来满足。您可以通过将msg文本收集到一个变量中以写入日志,以及使用Write-Host为控制台提供进度来完成。可以将此功能组合到您自己的Commandlet中,以最大程度地重用代码。
Write-Output
,您看不到它,因为这是最后编写的内容。合理的解决方法,但不是解决方案。可能有些东西消耗了无法处理尾随换行符的结果输出。
以下将光标移回上一行的开头。您可以将其放置在正确的水平位置(使用$ pos.X将其向侧面移动):
$pos = $host.ui.RawUI.get_cursorPosition()
$pos.Y -= 1
$host.UI.RawUI.set_cursorPosition($Pos)
您当前的输出是27个空格,因此$ pos.X = 27可能有效。
$pos.X
也可以产生正确的输出。问题是,如果将其通过管道传输到文件,则会显示两行。
它可能并不十分优雅,但确实可以满足OP的要求。请注意,ISE会与StdOut混淆,因此不会有输出。为了看到此脚本工作,它不能在ISE中运行。
$stdout=[System.Console]::OpenStandardOutput()
$strOutput="Enabling feature XYZ... "
$stdout.Write(([System.Text.Encoding]::ASCII.GetBytes($strOutput)),0,$strOutput.Length)
Enable-SPFeature...
$strOutput="Done"
$stdout.Write(([System.Text.Encoding]::ASCII.GetBytes($strOutput)),0,$strOutput.Length)
$stdout.Close()
[System.Console]
不能重定向到文件。
我作弊,但我相信这是解决所有要求的唯一答案。即,这避免了结尾的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.'
这里已经有太多答案了,没有人会在这里向下滚动。无论如何,还有一种解决方案,可以在文本末尾没有换行的情况下写:
带有编码的文件输出:
# a simple one liner
"Hello World, in one line" | Out-File -Append -Encoding ascii -NoNewline -FilePath my_file.txt;
# this is a test to show how it works
"Hello World".Split(" ") | % { "_ $_ _" | Out-File -Append -Encoding ascii -NoNewline -FilePath my_file.txt; }
控制台输出:
# a simple one liner
"Hello World, in one line" | Write-Host -NoNewline;
# this is a test to show how it works
"Hello World".Split(" ") | % { "_ $_ _" | Write-Host -NoNewline; }