windows - Hvorfor slutter min stderr-omdirigering ikke, når kommandoen er færdig? Og hvordan reparerer jeg det?

Indlæg af Hanne Mølgaard Plasc

Problem



I Windows, enten i kommandolinjen eller en batchfil, vil kommandoen 'DIR 2> NUL: 3> &2' (du kan erstatte 'DIR' med noget, selvom det ikke er en fil eller en kommando) gøre alle fejl fra da af mangler, medmindre du skriver '2> CON:' efter hver kommando. Hvorfor gør CMD det samme? Og hvordan får du det tilbage til normal uden at starte en ny CMD-proces? 'DIR 2> CON: 3> & 2 'vil kun fungere for den kommando alene.


EDIT: Dette vil også fungere med filer. 'DIR 2> TEXT.TXT 3> &2' Eventuelle fejl efter det bliver vedlagt filen.

Bedste reference


Her er et test script, der gengiver det problem, du ser.


@echo off
2>nul 3>nul (
  echo I want to see stream1
  1>&2 echo I don't want to see this stream2
  1>&3 echo I don't want to see this stream3
)
echo stream1 works fine
1>&2 echo stream2 is now "permanently" void. I don't see this.
1>&3 echo stream3 works fine


Og her er output


I want to see stream1
stream1 works fine
stream3 works fine


stderr (stream 2) er blevet deaktiveret 'permanent', selv for den overordnede CMD.EXE shell.


Du kan undgå det 'permanente' aspekt ved at gøre omdirigering i faser:


@echo off
2>nul (
  3>nul (
    echo I want to see stream1
    1>&2 echo I don't want to see this stream2
    1>&3 echo I don't want to see this stream3
  )
)
echo stream1 works fine
1>&2 echo stream2 works fine
1>&3 echo stream3 works fine


Og her er den ønskede output:


I want to see stream1
stream1 works fine
stream2 works fine
stream3 works fine


Jeg forstår virkelig ikke hvad der foregår. Men jeg har lavet nogle interessante eksperimenter. Tjek denne tråd: http://www.dostips.com/forum/viewtopic.php?f=3u0026amp;t=2836u0026amp;start= 30 [10]


Tillæg


Som Erbert har opdaget og delt i sin kommentar, er løsningen endnu nemmere, hvis du bare skifter omdirigeringens rækkefølge - ingen grund til at skille den.


@echo off
3>nul 2>nul (
  echo I want to see stream1
  1>&2 echo I don't want to see this stream2
  1>&3 echo I don't want to see this stream3
)
echo stream1 works fine
1>&2 echo stream2 works fine
1>&3 echo stream3 works fine


Opdater 2012-04-03
Jeg tror jeg endelig forstår mekanikerne i Windows CMD.EXE omdirigering. Jeg har en arbejdsteori, der fuldt ud tegner sig for alle de underlige opførsel, herunder hvorfor reversering af ordren forhindrer 'permanent' omdirigering. Det forklarer også Aacinis observation om at håndtere 3 ser ud til at være forbundet til CON: (Det er ikke, det er faktisk udefineret som i Windows-dokumentation).


Hovedpunkterne er:


1 - Når et håndtag (stream) omdirigeres, overføres den oprindelige definition til det første tilgængelige, ikke-definerede håndtag. Efterfølgende omdirigeringer udføres altid fra venstre mod højre.


2 - Når omdirigering er overstået, gendannes de oprindelige definitioner normalt. Men hvis der er en omdirigeringskæde, bliver restaureringen kun gjort 1 niveau dybt. Dette er kilden til 'permanent' omdirigering.


Rediger 2014-12-19: På anden måde synes restaureringen at være udført ved hjælp af en køstruktur (FIFO - First In First Out), når den skulle have været implementeret som en stak (LIFO - Last I første udgang).


3 - Når CMD.EXE udfører omdirigering, sparer den den nuværende definition i det ubestemte håndtag først, hvorefter det omdirigerer det første håndtag. Hvis det første håndtag omdirigeres til det oprindeligt undefined håndtag, så bliver det omdirigeret til dets oprindelige definition! Det er derfor echo hello 1>&3 output til konsollen.


De fulde teori og test tilfælde er tilgængelige i to på hinanden følgende stillinger på http://www.dostips.com/forum/viewtopic.php?p=14612#p14612.[11]

Andre referencer 1


Jeg undskylder for at skrive dette som et svar i stedet for en kommentar, men min 'kommentar' er for stor ...


I MS-DOS-standarden har alle løbende programmer åbnet disse Standardhåndtag : 0-STDIN (tastatur), 1-STDOUT (skærm), 2-STDERR (skærm), 3-STDAUX ) og 4-STDPRN (printer). Selvom Windows-dokumentation tydeligt angiver, at håndtag 3-9 er udefinerede, skal håndtere 3 have en særlig behandling af CMD.EXE. Jeg har tre grunde til at tænke på dette:


1- Håndtag 3 er tilsluttet CON: enhed (tastatur til input, skærm til udgang); håndtag 4-9 gør ikke:


C>ver

Microsoft Windows XP [Version 5.1.2600]

C>echo To handle 3 >&3
To handle 3

C>echo To handle 4 >&4
The handle could not be duplicated
during redirection of handle 1.

C>set /P var=From handle 3: <&3
From handle 3: Value entered in keyboard

C>echo \%var\%
Value entered in keyboard

C>set /P var=From handle 4: <&4
The handle could not be duplicated
during redirection of handle 0.


2- Den mærkelige opførsel af håndtag 3 angivet i det nuværende emne, der blev løst på to forskellige måder. Jeg opdagede, at hvis håndtagene 0, 1 eller 2 omdirigeres med håndtag 3 (og muligvis håndterer 4-9) bliver omdirigering af håndtag 0, 1 eller 2 'permanent'; Denne opførsel sker ikke, hvis håndtaget 0, 1 eller 2 er håndteringsværktøjet sidste i listen over omdirigeringer, der indeholder håndtaget 3. Dette problem undgås helt, hvis der håndteres 0, 1 eller 2 Omdirigeres med håndtag 4-9 i en hvilken som helst rækkefølge, men håndter ikke 3.


3- Resultaterne opnået med mit TypeOfHandle.com-program. Dette program er en ren MS-DOS-eksekverbar fil, der kontrollerer håndtaget angivet i parameteren og returnerer via errorlevel en værdi på 3 hvis håndtaget er forbundet til CONsole-enheden eller en værdi på 128, hvis håndtaget omdirigeres til en diskfil . Disse er resultaterne: [12]


C>typeofhandle 0

C>echo \%errorlevel\%
3

C>typeofhandle 0 < anyFile.txt

C>echo \%errorlevel\%
128

C>typeofhandle 1

C>echo \%errorlevel\%
3

C>typeofhandle 1 > anyFile.txt

C>echo \%errorlevel\%
128

C>typeofhandle 3

C>echo \%errorlevel\%
0

C>typeofhandle 3 <&3 anyFile.txt

C>echo \%errorlevel\%
0

C>typeofhandle 3 >&3 anyFile.txt

C>echo \%errorlevel\%
0


Håndtag 3-9 opfører sig underligt i et andet aspekt:


Resultaterne opnået med mit SetFilePointer.com program. Selvom håndtag 3-9 kan bruges i en Batch-fil for at opnå input/output fra/til flere filer på én gang, tillader denne mekanisme kun sekventiel adgang , fordi mit SetFilePointer-program ikke kan flytte filpegeren håndterer 3-9. SetFilePointer-programmet fungerer korrekt på håndtag 0, 1 og 2. Denne funktion gør det muligt at skrive et komplet Relational Database-program i Batch. Dette emne er beskrevet detaljeret i dette indlæg [13] [14]

Andre referencer 2


Problemet er med 3>&2. Filbeskrivelse 3 er ikke gyldig, og det ser ud til at forstyrre Windows på en eller anden måde. Lad det stå af, du behøver det ikke.


Se Microsofts dokumentation for den fulde behandling. [15]