PowerShell'de bir şeyin çıktısı nasıl alınır


210

Bir toplu iş dosyasından bir PowerShell komut dosyası çalıştırıyorum. Komut dosyası bir web sayfası getirir ve sayfanın içeriğinin "Tamam" dizesi olup olmadığını kontrol eder.

PowerShell betiği, toplu iş betiğine bir hata düzeyi döndürür.

Toplu komut dosyası , bir FTP otomasyon programı olan ScriptFTP tarafından yürütülür . Bir hata oluşursa, ScriptFTP'nin tam konsol çıktısını yöneticiye E-Posta yoluyla göndermesini sağlayabilirim.

PowerShell betiğinde, "Tamam" değilse web sitesinden dönüş değerini çıktılamak istiyorum, bu nedenle hata iletisi konsol çıktısına ve dolayısıyla durum postasına dahil edilir.

PowerShell için yeniyim ve bunun için hangi çıkış işlevinin kullanılacağından emin değilim. Üçünü görebiliyorum:

  • Yaz-Sunucu
  • Yaz-Çıktı
  • Yazım hatası

Windows eşdeğerine yazmak için kullanılacak doğru şey nedir stdout?

Yanıtlar:


196

Sadece bir şey çıktılamak PowerShell bir güzellik meselesidir - ve en güçlü yanlarından biridir. Örneğin, ortak Merhaba, Dünya! uygulama tek bir satıra indirgenir:

"Hello, World!"

Bir dize nesnesi oluşturur, yukarıda belirtilen değeri atar ve komut satırında son öğe olarak .toString()yöntemi çağırır ve sonucu STDOUT(varsayılan olarak) verir. Güzel şey.

Diğer Write-*komutlar, metni ilişkili akışlarına çıkarmaya özgüdür ve yerlerine bu şekilde sahip olurlar.


9
Gerçekte olan bu değil. Bu bir dizgi değişmez ifadesi ve boru hattındaki tek şey. Böylece eşittir "Hello, World!" | Out-Host. Out-HostÖte yandan nesneleri görüntüleme için PowerShell ana bilgisayarına gönderir ve uygulaması ana bilgisayara bağlıdır. Konsol ana bilgisayarı, bunları standart çıkış tutamacına (yol Out-Defaultboyunca geçerek) gönderir . Bununla birlikte, PowerShell ISE bunları çıkış bölmesinde görüntüler ve diğer ana bilgisayarlar tamamen başka şeyler yapabilir.
Joey

5
Nesneler de kör olarak dizeye dönüştürülmez, ancak onlarla ne yapılacağına karar veren bir formatlayıcıdan geçer . Bu nedenle Get-ChildItem, örneğin çıktıların bir tablo biçiminde geldiğini görürsünüz ve Format-Listbunun yerine birçok özelliğin (ör. WMI) varsayılanı vardır .
Joey

120

Bu durumda Write-Output'a ihtiyacınız olacağını düşünüyorum .

Gibi bir komut dosyanız varsa

Write-Output "test1";
Write-Host "test2";
"test3";

daha sonra, yeniden yönlendirilmiş çıktıya sahip bir komut dosyasını çağırırsanız, buna benzer bir şekilde yourscript.ps1 > out.txt, "out.txt" test2içindeki ekrana test1\ntest3\ngelirsiniz.

"Test3" ve Yaz-Çıktı satırının metninize her zaman yeni bir satır ekleyeceğini ve PowerShell'de bunu durdurmanın bir yolu olmadığını unutmayın (yani, echo -nPowerShell'de yerel komutlarla imkansızdır). İsterseniz ( Bash'de biraz temel ve kolay ) işlevselliği echo -nvarsa samthebest'in cevabına bakın .

Bir toplu iş dosyası bir PowerShell komutu çalıştırırsa, büyük olasılıkla Write-Output komutunu yakalar. Konsolda nelerin yazılması gerektiği ve nelerin olmaması gerektiği konusunda sistem yöneticileriyle "uzun tartışmalar" yaptım. Komut dosyası başarılı bir şekilde yürütülürse veya ölürse tek bilginin düzenlenmesi gerektiğine ve komut Write-Hostdosyasının yazarı olan her şeyin yürütme hakkında bilgi sahibi olması gerekebileceğini kabul ettik (hangi öğeler güncellendi, hangi alanlar ayarlandı, vb.) Yazma-Çıktı. Bu şekilde, sistem yöneticisine bir komut dosyası gönderdiğinizde runthescript.ps1 >someredirectedoutput.txt, her şeyin yolunda olup olmadığını kolayca görebilir ve ekranda görebilir. Ardından "someredirectedoutput.txt" dosyasını geliştiricilere geri gönderin.


9

Aşağıdaki Echo vs Write-Host iyi bir sergi olduğunu düşünüyorum . Test () 'in aslında bir ints dizisini nasıl döndürdüğüne dikkat edin, tek bir int değil, kolayca inanmaya neden olabilir.

function test {
    Write-Host 123
    echo 456 # AKA 'Write-Output'
    return 789
}

$x = test

Write-Host "x of type '$($x.GetType().name)' = $x"

Write-Host "`$x[0] = $($x[0])"
Write-Host "`$x[1] = $($x[1])"

Yukarıdakilerin terminal çıkışı:

123
x of type 'Object[]' = 456 789
$x[0] = 456
$x[1] = 789

Bütün gün buna bakabiliyorum ... Ama neden $x = testsadece baskı 123değil de baskı 456?
not2qubit

7

Bunların herhangi birini, varsayılan akışlara (çıktı ve hata) yazdıkları için senaryonuzda kullanabilirsiniz. Çıktıyı başka bir komuta aktarıyorsanız , daha sonra Write- Host'da sona erecek olan Write-Output'u kullanmak istersiniz .

Bu makalede farklı çıktı seçenekleri açıklanmaktadır: PowerShell O çıktı içindir


1
Bağlantı için teşekkürler. Tanrım, bu karmaşık . Write-host bir tür son nokta veya yıkama fonksiyonu ise, bunu deneyeceğim ve rapor vereceğim.
Pekka

3
Write-Host "Found file - " + $File.FullName -ForegroundColor Magenta

Macenta "System.ConsoleColor" numaralandırıcı değerlerinden biri olabilir - Siyah, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gri, DarkGray, Mavi, Yeşil, Mavi, Kırmızı, Macenta, Sarı, Beyaz.

+ $File.FullNameİsteğe bağlıdır ve gösteriler nasıl dize içine bir değişken koymak.


2

PowerShell'i bu sinir bozucu yeni satırlara atlatamazsınız. Bunu yapan bir komut dosyası veya cmdlet yoktur.

Elbette Write-Host mutlak saçmalıktır, çünkü yönlendiremez / yönlendiremezsiniz! Sadece kendiniz yazmak zorundasınız:

using System;

namespace WriteToStdout
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args != null)
            {
                Console.Write(string.Join(" ", args));
            }
        }
    }
}

Örneğin

PS C:\> writetostdout finally I can write to stdout like echo -n
finally I can write to stdout like echo -nPS C:\>

Bunu powershell'in kendisinde yapabilirsiniz. [System.Console] :: Write ("stringy") Ancak, powershell'de hiç yönlendiremezsiniz.
Nicholi

1
Tabi ki yapabilirsin. Bu soruya
Slogmeister Extraordinaire

1

Stdout'un Windows eşdeğerine yazmak için kullanılacak doğru şey nedir?

In etkisi , ama çok maalesef , hem Windows PowerShell ve PowerShell Çekirdek v7.0 itibariyle göndermek bütün bunların 6 (!) Bir çıkış akışları için stdout zaman denilen dışarıdan PowerShell en yoluyla CLI .

  • Geriye dönük uyumluluk uğruna düzeltilmesi muhtemel olmayan bu sorunlu davranışın tartışılması için bu GitHub sorununa bakın .

  • Uygulamada bu, çıktı gönderdiğiniz her PowerShell akışının harici bir arayan tarafından stdout çıktısı olarak görüleceği anlamına gelir :

    • Eğer gelen aşağıdakileri çalıştırırsanız Örneğin, cmd.exegörürsünüz hiçbir stdout yönlendirme nedeniyle, çıkış NULPowerShell akışları herkese eşit uygulanır:

      • C:\>powershell -noprofile -command "Write-Error error!" >NUL
    • Ancak - merakla - eğer stderr'yi yönlendirmek , PowerShell yapar stderr'e onun hata akışı göndermek , böylece ile 2>size olabilir hatasız akışı çıkışı seçici yakalamak; 'hi'dosyadaki hata akışı çıktısını yakalarken aşağıdaki çıktılar sadece - başarılı akış çıktısı err.txt:

      • C:\>powershell -noprofile -command "'hi'; Write-Error error!" 2>err.txt

İstenen davranışı olduğu:

  • PowerShell'in başarı çıkış akışını (sayı 1) stdout'a gönderin .
  • İşlemler arasında yalnızca 2 çıkış akışının ( veriler için stdout (standart çıktı) ve hata mesajları ve diğer tüm mesaj türleri için stderr (standart hata) olduğu göz önüne alındığında, diğer tüm akışlardan çıktıyı stderr'e gönderin , tek seçenek budur. durum bilgisi olarak - veri değildir .

  • Şu anda saygı görmese bile, kodunuzda bu ayrımın yapılması tavsiye edilir .


İç PowerShell :

  • Write-Hostolduğu için görünen çıkışı ve atlar başarı çıkış akışı - gibi, çıkış ne (direkt olarak) bir değişken yakalanan veya bastırılmış veya yeniden yönlendirilmiş olabilir.

    • Asıl amacı basitçe kullanıcı geri bildirimi oluşturmak ve basit, konsol tabanlı kullanıcı arayüzleri (renkli çıktı) oluşturmaktı.

    • Nedeniyle yakalanan veya yönlendirilecek öncesinde yetersizlik, yapılan PowerShell sürüm 5'e Write-Hostyeni tanıtılan için bilgi akışının (sayı 6), bu yüzden o zamandan beri olan yakalama ve yönlendirme mümkün Write-Hostçıktı.

  • Write-Error" Hata" terimi , hata akışına (sayı ) sonlandırmayan hatalar yazmak içindir 2; kavramsal olarak, hata akışı stderr'e eşdeğerdir.

  • Write-Outputkavramsal olarak stdout'a eşdeğer olan başarı [çıktı] akışına (sayı 1) yazar ; bunun yazma için akış verileri için (sonuçlar).

    • Bununla birlikte, PowerShell'in örtülü çıktı özelliği nedeniyle açık kullanımı Write-Outputnadiren gereklidir :
      • Açıkça yakalanmayan, bastırılmayan veya yönlendirilmeyen herhangi bir komut veya ifadeden çıktı otomatik olarak başarı akışına gönderilir ; örn. Write-Output "Honey, I'm $HOME"ve "Honey, I'm $HOME"eşdeğerdir, ikincisi sadece daha kısa değil aynı zamanda daha hızlıdır.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.