windows - Sådan undertrykkes fejlmeddelelsen 'permission denied' output ved omdirigering af tekst til en skrivebeskyttet fil for nogle brugere?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har det problem, at min batch er på et netværksdrev, og ikke alle mennesker har skrive tilladelse til denne vej. Normalt batch loggen også nogle oplysninger.


Jeg vil gerne undertrykke permission denied info i tilfælde af ingen skrive tilladelse. Min antagelse er, at jeg skal omdirigere standardfejlen til nul.


Men dette eksempel virker ikke. Jeg vil få en permission denied. Det er OK, hvis loggen ikke oprettes, men jeg vil ikke se en permission denied fejlmeddelelse. Denne fejlmeddelelse skal omdirigeres til stderr.


echo test 1> c:Windowslog.txt 2> nul

Bedste reference


Hvis du bruger syntaksen


echo data >log.txt 2>nul 


du beder om at sende output genereret af kommandoen echo til logfilen og de fejl, der genereres af kommandoen til null.


Dit problem er, at udgangen til stderr ikke genereres ved udførelsen af ​​kommandoen echo, men fra en fejl i omdirigeringshåndteringsrutinerne, der udføres før selve echo.


Du skal flytte stderr-omdirigeringsoperationen et niveau op


2>nul ( >log.txt echo data )


Nu omdirigerer stderr-omdirigering alt inden for parentesen, det vil sige omdirigeringsoperationen og udførelsen af ​​echo.

Andre referencer 1


Kommandolinjen


echo test > c:Windowslog.txt 2> nul


omdirigerer standard output af kommandoen ECHO til fil c:Windowslog.txt og standardfejl outputen af ​​kommandoen ECHO til enhed NUL .


test med pladsen før omdirigeringsoperatøren > er skrevet til c:Windowslog.txt, som normalt ikke fungerer, fordi denne mappe er skrivebeskyttet og bruges her som et eksempel til netværksmappen med individuel adgang tilladelser.


Kommandoen ECHO udsender aldrig noget til at håndtere STDERR . Derfor har omdirigering af standardfejludgangen fra kommandoen ECHO til enheden NUL aldrig nogen virkning.


Hvad du virkelig vil undertrykke fejludgangen af ​​cmd ved omdirigering af ECHO output til filen log.txt i måske beskyttet mappe, som kræver en anden syntaks.


Du kan bruge:


(>"\%SystemRoot\%log.txt" echo test) 2>nul


Eller lettere at læse:


@echo off
(
    >"\%SystemRoot\%log.txt" echo test
) 2>nul


Kommandolinjen ECHO er vedlagt i en kommandoblokk, der starter med åbning parentes ( og slutter med matchende lukke parentes ). Alt, der udføres af en kommando i denne kommandolinje til at håndtere STDERR omdirigeres til enheden NUL , som indeholder fejlmeddelelsesudgangen af ​​cmd, hvis den nuværende bruger ikke har nogen tilladelse at oprette fil log.txt i outputmappen eller hvis outputfilen allerede eksisterer og har skrivebeskyttet attributtsæt, eller hvis outputfilen åbnes i øjeblikket af et program, der åbnede det med en fildeling, skriv lås til andre applikationer .


Omdirigeringsoperatøren > og filnavnet er angivet på ECHO kommandolinjen ved begyndelsen for at kunne udgive også en tekst med nummer 1 ... 9 i slutningen uden at skrive et efterfølgende rum i filen \%SystemRoot\%log.txt.


Som kommandoblød bruges omkring ECHO kommandolinje, kræver udgangen af ​​en lukkekurv ) af ECHO nu at flytte denne karakter med karet karakter ^ som vist i eksempel nedenfor:


@echo off
(
    >"\%SystemRoot\%log.txt" echo '(' and '^)' are round brackets/parentheses.
) 2>nul


En langsommere alternativ løsning bruger forsinket ekspansion:


@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "TextToOutput='(' and ')' are round brackets/parentheses. '!' is an exclamation mark."
setlocal EnableDelayedExpansion
(
    echo !TextToOutput!>\%SystemRoot\%log.txt
) 2>nul
endlocal
endlocal


\%SystemRoot\% er allerede erstattet af C:Windows (eller hvad som helst stien til Windows-mappen) ved at analysere hele kommandoblokken ved hjælp af Windows-kommandotolk før udførelsen af ​​den første linje inden for ( ... ). Men værdien af ​​miljøvariabel TextToOutput erstatter ikke !TextToOutput! før ECHO udføres, hvilket gør det sikkert nu at angive omdirigeringsoperatøren i slutningen uden et mellemrum før for at undgå et efterfølgende rum i filen på outputlinjen.


For at forstå de anvendte kommandoer og hvordan de virker, skal du åbne et kommandopromptvindue, udføre de følgende kommandoer, og læs helt alle hjælpesider, der vises for hver kommando, meget omhyggeligt.



  • cmd /?

  • echo /?

  • endlocal /?

  • set /?

  • setlocal /?



Og læs også Microsoft TechNet-artiklen Brug af kommandoredirection-operatører. [51]





Det er også muligt at anvende en helt anden teknik.


Batchfilen omdirigerer alt til en midlertidig fil i mappen til midlertidige filer fra den aktuelle bruger. Når den færdige logfil er færdig, kopieres den til netværksmappe eller tilføjes til netværksmappe med undertrykkelse af fejlmeddelelsen, hvis brugeren ikke har nogen skrive tilladelse på netværksmappen.


Eksempelkode til brug for denne teknik:


@echo off
set "LogFile=\%TEMP\%\%~n0.tmp"
del "\%LogFile\%" 2>nul

>>"\%LogFile\%" echo test
rem Other commands with output also redirected to log file.

if exist "\%LogFile\%" (
    rem copy "\%LogFile\%" "\%~dp0log.txt"
    copy /B "\%~dp0log.txt"+"\%LogFile\%" "\%~dp0log.txt"
    del "\%LogFile\%"
) >nul 2>&1
set "LogFile="


Den første COPY kommandolinje kommenteret i batchkode ovenfor overskriver logfilen i mappen i batchfilen med den nyoprettede logfil.


Den anden COPY kommandolinje tilføjer den nyoprettede logfil til allerede eksisterende logfil i mappen i batchfilen.

Andre referencer 2


Et ciffer direkte før en omdirigerer omdirigerer det-nummer -enheden.


1 er standard output, så du forsøger at omdirigere udgangen echo til c:windows - sikkert beskyttet og også en mappe, ikke en fil.


Hvis dit formål (du siger ikke) er at omdirigere test 1


 1>file echo test 1 2>nul


men da du ikke udtrykkeligt siger hvad du vil gøre, er det et gæt.