Windows cmd çıkışının standart girişe yönlendirilmesi (> & 0)


4

Stackoverflow hakkındaki bir sorudan , / from stdin akışına yönlendirme ile test yapıyorum. Ve bu testler stdin akışına veri göndermeye çalışıyor, sadece ne olduğunu görmek için, görünüşte kaotik bir davranışla bitiyor.

Komutlar gibi

echo testing >&0
dir >&0 
cls >&0

üretecek System can not write to the specified device(stdin, salt okunur bir akış olabilir, belki)

  • vol >&0 herhangi bir hata göstermiyor

  • set /p "var=prompt" >&0 bilgi istemini gösterme ve herhangi bir hata göstermemeye çalışarak girişi bekler

  • pause >&0 hatasız bekleyecek, ancak bir tuşa basıldığında hata gösterilecek

Ve son saman stderr yönlendirmesidir. Çıktıları stderr'e gönderen dahili komutlar kullanılırken, stdin'e yönlendirilir,

call "noFile" 2>&0
dir  "|" 2>&0

Sonuç cmd.exe kapatılacak olmasıdır. Ama her zaman değil. Gibi şeyler

dir "|" * 2>&0
dir * "|" 2>&0

Sorunsuz bir şekilde çalışın, stderr'e gönderilen metni gizleyin ve bilginin kalanını yazdırın.

Öyleyse, soru şu, bu bir hata mı, bir yerde belgeleniyor mu ve bulamıyorum veya beklenen davranış bu mu ve eksik olduğum belli bir şey var mı?

Yanıtlar:


4

CMD.EXE'nin yeterince belgesiz olduğu göz önüne alındığında, beklenen davranışın ne olması gerektiğinden emin değilim. Beklenen davranışın ne olduğuna dair hiçbir belge görmedim. Bu yüzden davranışlardan herhangi birinin hata olup olmadığına dair kesin bir cevap verebilecek birini bulmakta zorlanacağınızı düşünüyorum. Ama kesinlikle bunun tutarsız olduğuna katılıyorum ve en azından bana göre bir tasarım hatası gibi görünüyor.

Belirli bir komutun davranışının tekrarlanabilir göründüğü için durumu kaotik olarak nitelendirmezdim. Ancak CMD.EXE tutarsız, herhangi bir komutun sınamadan nasıl davranacağını tahmin etmenin bir yolunu göremiyorum.

Hiçbir açıklamam yok, ancak davranışların rafine sınıflandırılmaları var.

Stdout veya stderr komutunun stdin komutuna yeniden yönlendirilmesi, hiçbir komut aslında yeniden yönlendirilen çıktıya hiçbir şey yazmaya çalışmadığı sürece mükemmel çalışır. Garip davranış, yalnızca bir iç komut stdin'e yönlendirildikten sonra stdout'a veya stderr'ye yazmaya çalıştığında ortaya çıkar.

Testlerinizi genişlettim ve aşağıdaki belirgin davranışları gördüm:

Yönlendirilmiş STDERR 2>&01

Kapsamlı testler yapmadım, ancak stderr'e yazılan her iç komut stderr stdin'e yeniden yönlendirilmişse derhal komut oturumunu sonlandıracak. Örnekler şunları içerir:

cd invalidPath 2>&0
vol x 2>&0
copy nonExistentFile 2>&0
move nonExistentFile 2>&0
set nonExistentVariable 2>&0
dir nonExistentFile 2>&0

Bir istisna olduğunu düşündüğünüz şey aslında asla stderr'e yazmadı. Yeniden yönlendirme yapmadan aşağıdakileri deneyin; hata mesajı olmadığını göreceksiniz:

dir nonExistentFIle *

Bu nedenle, stderr stdin'e yönlendirilirse, komutun komut oturumunu sonlandırması için hiçbir neden yoktur.

DIR, yalnızca sağlanan tüm dosya maskelerinde eşleşen bir dosya bulamazsa bir hata mesajı basar.

:: This prints an error message
dir nonExistentFile1 nonExistentFile2

:: So this terminates the command session
dir nonExistentFile1 nonExistentFile2 2>&0


Yönlendirilmiş STDOUT 1>&0

Yönlendirilen stdout için gördüğüm davranışlar şunlardır:

1) Çıkış, hata mesajı olmadan etere gider.

Örnekler:

vol >&0
copy /-y file1 existingFile2 >&0
move /-y file1 existingFile2 >&0


2) Çıkış başarısız olur ve stderr'de bir hata mesajı görüntülenir. Tek bir komut, her başarısızlık stdout'a yazma girişimi için bir tane olmak üzere birden fazla hata mesajı oluşturabilir.

Örnekler:

cd >&0
echo Hello >&0

:: This generates 2 error messages, one for the time,
:: and another for the subsequent empty line
time /t >&0


3) Çıkış başarısız olur ve toplu işlem sonlandırılır. Aktif SETLOCAL, bir ARAÇ alt rutinde hata oluşursa, toplu iş sona ermesinden sonra bile etkin kalır. Bu bakımdan, ölümcül bir sözdizimi hatası gibi davranır.

Şimdiye kadar sadece bir komutun bu davranışı sergilediğini gördüm:

dir >&0

DIR komutunun, girişilen her giriş satırı için bir hata mesajı oluşturmasını beklerdim. Ancak ilk satırdaki başarısızlıktan sonra sona ermiş gibi görünüyor ve toplu işlem de iptal edildi.


4) Bazı komutlar birden fazla davranış sergiler.

Örnekler:

:: This SET command generates an error message for each
:: defined variable (behavior 2)
set >&0

:: But this SET command fails to display the prompt without
:: error message (behavior 1). Note that the echo of user input
:: is written directly to :con. It does not use stdout or stderr.
set "var=prompt" >&0

:: A single PAUSE exhibits both behaviors 1 and 2. The prompt to
:: press a key simply dissapears, and the echo of the user input
:: generates an error. Note that in this case, the echo of user
:: input is written to stdout.
pause >&0

Tabii ki. Bir dirşey bulunduğunda komutun stderr'ye yazmadığını görmedim . Ve evet, tutarsızlık kesin terimdir, teşekkür ederim.
MC ND

0

Bu hatayı 2010 yılında yanlışlıkla keşfettim. Sonunda hatayı keşfettim - stderr'i 0 akışına (geçerli işlem için stdin) yeniden yönlendirmek mantıklı gelmiyor ve cmd.exe bu senaryo için bir işleyici kullanmıyordu, dışarı. Doğru sözdizimi şuydu:

dir 2> nul (sadece hatayı yönlendirmek isteseydim)

veya

dir 2> nul 1> & 2 (eğer başarılı çıktıları yönlendirmek istersem).

Temel olarak, herhangi bir yerleşik komut için CMD.EXE'de yalnızca işlenmeyen bir istisna. İşte birkaç yıl önceki yazım: http://dnlongen.blogspot.com/2013/05/how-to-crash-windows-shell.html


Teşekkür ederim. Bu bir hata değildi. Sizin gibi bazen hata ayıklayıcısını bir şeye bağlayıp oynama şansım olur. Komut işlemcisi stderr'e yazamıyorsa (olmamalıdır) doğrudan çıktığını biliyorum (önceki testlerden). Görmediğim şey "bazen" neden olmadı. Dbenham'ın görmediğimi işaret ettiği gibi, "sorunlu" durumlarımın stderr'e yazmadığıydı.
MC ND

0

Bir göz atın https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true (arşivlenmiş)

>& Writes the output from one handle to the input of another handle.
<& Reads the input from one handle and writes it to the output of another handle.

& Yeniden yönlendirme işleci, belirtilen bir tanıtıcıdan belirtilen başka bir tanıtıcıya çıktıyı veya girişi kopyalar. Bir tanıtıcıyı çoğalttığınızda, tanıtıcının orijinal oluşumunun tüm özelliklerini çoğaltırsınız. Örneğin, bir tanıtıcı salt yazma erişimine sahipse, o tanıtıcının tüm kopyaları yalnızca yazma erişimine sahiptir. Salt okunur erişimi olan bir tanıtıcıyı salt okunur erişimi olan bir tanıtıcıya çoğaltamazsınız.


Lütfen soruyu tekrar dikkatlice okuyunuz. Yanıtınız yok değil orijinal soruya cevap. OP'nin sorusundaki garip davranışların hiçbirini açıklama girişiminde bulunmazsınız. Lütfen iyi bir cevabın nasıl olduğunu görmek için kabul edilen cevabı okuyun.
DavidPostill

Hatamı alırsınız, haklısınız: cevabım neden bazen hata döndürdüğünü, bazen neden çökmediğini veya çökmediğini açıklamıyor. Beklenilen davranış olarak her zaman hatayı ("yazamıyorum ...") göstermesi gerektiğini belirtir, bu nedenle @ David-Longenecker'in dediği gibi bir hata gibi görünür ve blogunda açıklar dnlongen.blogspot.com/2013/05/how-to -crash-windows-shell.html
joanmib
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.