回答:
Write-Host -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 3.0から利用可能な進行状況情報を含むPowerShellウィンドウの上部にバーを表示します。マニュアルを参照してください。詳細。
# 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
ます。合理的な回避策ですが、解決策ではありません。
はい、他の回答には状態があるため、Write-Outputでそれを行うことはできません。PowerShellが失敗した場合は、.NETに切り替えます。ここには.NETの回答もいくつかありますが、必要以上に複雑です。
ただ使用する:
[Console]::Write("Enabling feature XYZ.......")
Enable-SPFeature...
Write-Output "Done"
純粋なPowerShellではありませんが、動作します。
Write-Host
、人々が期待しないことを除いて、と同じように動作するため、反対投票されました。
ファイルに書き込むには、バイト配列を使用できます。次の例は、ファイルを追加できる空の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を使用して、少なくともstdoutに対してWrite-Outputが実際に出力を改行することでした。文字80でハードラップされるため、XMLテキストをstdoutに書き込もうとして成功しませんでした。
回避策は使用することでした
[Console]::Out.Write($myVeryLongXMLTextBlobLine)
これはPowerShell v3の問題ではありませんでした。そこでWrite-Outputが正しく動作しているようです。
PowerShellスクリプトの呼び出し方法によっては、使用する必要がある場合があります
[Console]::BufferWidth =< length of string, e.g. 10000)
stdoutに書き込む前。
PowerShellでこれを行う方法はないようです。以前の答えはすべて正しくありません。なぜなら、それらは振る舞いを振る舞わないが、とにかくこの問題はないWrite-Output
ような振る舞いをするからWrite-Host
です。
closesソリューションはWrite-Host
、-NoNewLine
パラメーターで使用するようです。これは一般的に問題となるパイプではできませんが、Write-Host => Export to a fileで説明されているようにこの関数をオーバーライドする方法があるため、出力ファイルのパラメーターを簡単に受け入れることができます。これはまだ良い解決策には程遠いです。これをStart-Transcript
使用するとより使いやすくなりますが、そのコマンドレットにはネイティブアプリケーションに問題があります。
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でこれらの厄介な改行を省略することはできません。スクリプトやコマンドレットはありません。もちろん、Write-Hostはリダイレクト/パイプできないため、まったくナンセンスです。
それでも、独自のEXEファイルを作成してそれを行うことができます。これは、Stack Overflowの質問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コマンドレットの最後のCRLFは抑制されません。そのためには、独自のコマンドレットを作成するか、ここにリストされている他の複雑な回避策のいずれかを使用するか、Microsoftが-NoNewline
Write-Outputのオプションをサポートすることを決定するまで待つ必要があります。
ログファイルに書き込むのではなく、テキストプログレスメーターをコンソールに提供するという要望(つまり、「....」)も、Write-Hostを使用して満たす必要があります。ログに書き込むためにmsgテキストを変数に収集することと、コンソールに進行状況を提供するためにWrite-Hostを使用することの両方を行うことができます。この機能を独自のコマンドレットに組み合わせて、コードを最大限に再利用できます。
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
。問題は、ファイルにパイプすると、2つの別々の行が表示されることです。
それはひどくエレガントではないかもしれませんが、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; }