2017-01-26 3 views
3

Nehmen wir an, dass ich diesen Code haben:Batch - Echo alle Variablen in der Batchdatei gesetzt

@echo off 
set "var=value" 
echo %var% 

Nun meine Frage ist: Wie alle Variablen in der Datei Echo eingestellt?

Ich weiß, was Sie tun können:

set 

Und es werden alle Variablen angezeigt werden soll. Es zeigt:

ALLUSERSPROFILE=C:\ProgramData 
APPDATA=C:\Users\foma\AppData\Roaming 
CommonProgramFiles=C:\Program Files\Common Files 
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files 
CommonProgramW6432=C:\Program Files\Common Files 
... 

Ich möchte, dass es zeigt:

var=value 

Ich weiß, ich set var tun können alle Variablen mit var, aber in meinem Fall alle meine Variablen „importiert“ von einem anderen Start anzuzeigen Batch-Datei, daher weiß ich nicht, wie der Variablenname beginnt. Irgendwelche Ideen?

+0

Löschen Sie die Umgebung aller Variablen und legen Sie dann die Variablen fest du brauchst. Eine Diskussion über diese Technik wurde gesehen, weil sie in manchen Fällen bei der Leistung hilft. – Squashman

+0

@Squashman Ich würde diese Lösung nicht empfehlen. Es erfordert eine eingehende Untersuchung aller Befehle, die Sie verwenden werden, und aller Umgebungsvariablen, die das Betriebssystem konfiguriert hat. Es wäre sogar einfacher, einer Benennungskonvention zu folgen und zu entscheiden, Variablen in einem Skript mit einem gegebenen Muster beginnen zu lassen und nur nach diesem Muster mit 'find' oder' findstr' zu suchen. Aber auch das hat die Unannehmlichkeit, dass Änderungen an bereits vorhandenen Variablen nicht erkannt werden. Vielleicht kann das OP mehr Spezifikationen geben. –

+1

@ HackR_360 wofür verwenden Sie es? Um die Veränderungen in der Umwelt rückgängig zu machen? Müssen Sie auch Änderungen an Variablen erkennen, die vor der Ausführung des Skripts bestanden haben?Antworten auf diese Fragen können zu einfacheren Lösungen führen. –

Antwort

3

Dies vergleicht die ursprüngliche cmd Umgebung (gespeichert in einer Datei) mit der aktuellen. Sie können die Erstellung Datei ändern, wenn Sie eine andere Check

@echo off 
    setlocal enableextensions disabledelayedexpansion 

    rem We need a temporary file to store the original environment 
    for %%f in ("%temp%\original_%random%%random%%random%.tmp") do (

     rem Retrieve the original environment to the temporary file 
     start /i /wait /min "" "%comspec%" /c">""%%~ff"" set " 

     rem We need two flag variables. Prepare two names that "should" not collide 
     for /f "tokens=1,2" %%d in ("_&d&%random%%random%_ _&m&%random%%random%_") do (

      rem %%d will be used to determine if we will check for variable deletion 
      rem  on the first inner pass 
      rem %%e will be used for matching variables between existing/original variables 
      set "%%d=" 

      rem Retrieve the current environment contents 
      for /f "delims= eol==" %%a in ('set') do (

       rem We have not found matching variables 
       set "%%e=" 

       rem Search a match in original set of variables 
       for /f "usebackq delims= eol==" %%o in ("%%~ff") do (

        rem If variables match, flag it, else check for variable 
        rem deletion is this is the first loop over the original file 
        if %%a==%%o (set "%%e=1") else if not defined %%d (
         for /f "delims==" %%V in ("%%~o") do if not defined %%V (echo(%%V=) 
        ) 
       ) 

       rem If no match found, output changed value 
       if not defined %%e (echo(%%a) 

      rem Now all the variable deletion has been checked. 
      ) & if not defined %%d set "%%d=1" 

     rem Cleanup flag variables 
     ) & set "%%d=" & set "%%e=" 

    rem Cleanup temporary file 
    ) & del "%%~ff" 

nicht so viel Code benötigen, wie es scheint, sobald wir die Kommentare

@echo off 
    setlocal enableextensions disabledelayedexpansion 
    for %%f in ("%temp%\original_%random%%random%%random%.tmp") do (
     start /i /wait /min "" "%comspec%" /c">""%%~ff"" set " 
     for /f "tokens=1,2" %%d in ("_&d&%random%%random%_ _&m&%random%%random%_") do (
      set "%%d=" 
      for /f "delims= eol==" %%a in ('set') do (
       set "%%e=" 
       for /f "usebackq delims= eol==" %%o in ("%%~ff") do (
        if %%a==%%o (set "%%e=1") else if not defined %%d (
         for /f "delims==" %%V in ("%%~o") do if not defined %%V (echo(%%V=) 
        ) 
       ) 
       if not defined %%e (echo(%%a) 
      ) & if not defined %%d set "%%d=1" 
     ) & set "%%d=" & set "%%e=" 
    ) & del "%%~ff" 

bearbeitet nur für den Abschluss zu entfernen. Als Dbenham-Punkte kann der vorherige Code keine Variablen mit Zeilenvorschub in ihren Namen oder Werten verarbeiten. Dies ist eine Hybrid-Batch-Datei (speichern Sie als Beispiel checkEnvironment.cmd Datei), die diesen Fall behandeln kann.

@if (@[email protected]) @then /* Batch zone ------------------------------------ 
@echo off 
    setlocal enableextensions disabledelayedexpansion 
    call :processCurrentEnvironment "%~f1" 
    goto :eof 

:processCurrentEnvironment 
    call "%systemroot%\system32\cscript.exe" //nologo //e:JScript "%~f0" /saved:"%~1" 
    goto :eof 

*/ @end 
// Javascript zone ----------------------------------------------------------- 

var environment = WScript.CreateObject('WScript.Shell').Environment('PROCESS'); 
var savedFileName = WScript.Arguments.Named.Item('saved'); 


    if (!savedFileName){ 
     // If no saved file name present, output current environment 
     for (var e = new Enumerator(environment); !e.atEnd(); e.moveNext()){ 
      WScript.StdOut.Write(e.item() + '\0\r\n'); 
     }; 

    } else { 
     // Retrieve saved environment to compare against current one 
     var savedEnvironment = retrieveSavedEnvironment(savedFileName); 

     // For each element in the current environment 
     for (var e = new Enumerator(environment); !e.atEnd(); e.moveNext()) { 

      // retrieve { variable: , value: } representation of the variable 
      var buffer = splitEnvironmentVariable(e.item()); 

      if (buffer) { 
       // if the current variable does not exist in the saved version 
       // or if the current value does not match the previous one 
       // then dump the current variable 
       if (
        ! savedEnvironment[buffer.variable] 
        || savedEnvironment[buffer.variable].value !== buffer.value 
       ) outputVariable(buffer); 

       // in any case, this is a processed variable 
       delete savedEnvironment[buffer.variable]; 
      } 
     }; 

     // any saved variables still present are deleted variables, show them 
     for (var e in savedEnvironment) outputVariable(e); 
    }; 

// - Helper functions ---------------------------------------------------------- 

// Process the contents of the saved file to generate a { {variable: , value: }, ... } 
// representation of the saved environment 

function retrieveSavedEnvironment(savedFileName) { 
    var savedEnvironment = {}; 
    var buffer = readFile(savedFileName).split('\0\r\n'); 
    for (var i in buffer) if (buffer[i] = splitEnvironmentVariable(buffer[i])) { 
     savedEnvironment[buffer[i].variable] = buffer[i]; 
    }; 
    return (savedEnvironment); 
}; 

// Read the contents of the saved file - FSO can not be used because we are 
// writing nulls (ascii 0x00 character) to separate variables 

function readFile(savedFileName){ 
    var buffer = ""; 
    if (
     WScript.CreateObject('Scripting.FileSystemObject').FileExists(savedFileName) 
    ){ 
     var stream = WScript.CreateObject('ADODB.Stream'); 
     stream.Open(); 
     stream.Type = 2 
     stream.Charset = 'ascii'; 
     stream.LoadFromFile(savedFileName); 
     buffer = stream.ReadText(); 
     stream.Close(); 
    }; 
    return (buffer); 
}; 

// Convert variable=value to { variable: , value: } 

function splitEnvironmentVariable(text){ 
    text = (/^([\s\S][^=]*)=([\s\S]+)/).exec(text); 
    return (
     text 
     ? { variable : text[1] , value : text[2] } 
     : text 
    ); 
}; 

// Write the variable with its value or only the variable name 

function outputVariable(variable){ 
    if (typeof variable === 'object') { 
     WScript.StdOut.WriteLine(variable.variable + '=' + variable.value); 
    } else { 
     WScript.StdOut.WriteLine(variable + '='); 
    }; 
}; 

im Weg gebracht oder in demselben Ordner, die Batch-Dateien, können Sie es als

@echo off 
    setlocal enableextensions enabledelayedexpansion 

(SET LF=^ 
%=this line is empty=% 
) 

    rem Variables to delete 
    set "variableToDelete=1" 
    set "my!lf!var1=my!lf!data" 

    set "originalEnvironment=%temp%\original_%random%%random%%random%.tmp" 

    rem save environment 
    >"%originalEnvironment%" call checkEnvironment.cmd 

    rem Create new variable2 
    set "thisIsNew=value" 
    set "anotherOne=1" 

    rem Create another problematic variable 
    set "my!lf!var2=my!lf!data" 

    rem Delete variables 
    set "variableToDelete=" 
    set "my!lf!var1=" 

    rem Dump environment changes 
    call checkEnvironment.cmd "%originalEnvironment%" 

    rem Remove temporary file 
    del /q "%originalEnvironment%" 

zu bekommen einen Ausgang als

W:\>testEnv.cmd 
anotherOne=1 
my 
var2=my 
data 
thisIsNew=value 
my 
var1= 
variableToDelete= 
W:\> 
+1

Sehr schön. Funktioniert bei mir. Natürlich wird dies fehlschlagen, wenn ein variabler Wert (oder Name!) Newline enthält, aber dann glaube ich nicht, dass es Batch-Lösungen gibt, die das verarbeiten können. Ich glaube, das OP möchte herausfinden, was die zuletzt erstellte Batch-Datei ändert, und nicht, welche Änderungen seit dem Start der Befehlssitzung vorgenommen wurden. Sie bestätigen jedoch, dass die Dateierstellung nach Bedarf geändert werden kann. – dbenham

+0

@dbenham, ich sehe nicht, wie man mit der neuen Linie von der reinen Reihe anfaßt. Für den Fall, dass jemand es nützlich finden könnte, habe ich eine Hybrid-Version hinzugefügt, um damit umzugehen. –

+0

funktioniert! Danke vielmals! –

7
@echo off 
setlocal 
set>originalfile.txt 
... 
:: list environment changes 
set|findstr /x /L /g:originalfile.txt 

Sollte funktionieren - die Startwerte Schnappschuss, dann ist die findstr Linie sollten Sie alle Änderungen zeigen (mit Ausnahme von Deletionen) - zumindest in der Theorie, das ist nur ein on-the-fly-Vorschlag.

+0

eine großartige Umsetzung der Reflexion für Fledermaus-Dateien! –

+1

+1 - Dies funktioniert für die meisten Werte. Aber es kann fehlschlagen, wenn originalfile.txt '' ''' oder '\\' aufgrund von FINDSTR-Escape-Problemen bei der Verwendung von' g: file' enthält – dbenham

+0

Erstes Verdoppeln aller '\' in 'originalfile.txt' dann Ersetzen jedes' "' durch '\ "durch etwas mehr Code sollte der Trick für den Code für (fast fast) alle Werte funktionieren, sollte es nicht, @dbenham? Auch +1 von mir! – aschipfl

0

sowieso die einfachste Art und Weise verwenden können:

@echo off 
setlocal enabledelayedexpansion 
set "oldfile=oldfile.txt" 
set "newfile=newfile.txt" 
del %oldfile% >nul 2>nul 
del %newfile% >nul 2>nul 
for /f %%a in ('set') do echo %%a>>%oldfile% 
::---------------------set-vars-here--------------------- 
set "testone=testonestring" 
set "testtow=12324" 
::------------------------------------------------------- 
for /f %%a in ('set') do echo %%a>>%newfile% 
for /f %%a in (%newfile%) do (
find "%%a" %oldfile% >nul 2>nul 
if !errorlevel! NEQ 0 (
set "string=%%a" 
echo !string! 
) 
) 
del %oldfile% >nul 2>nul 
del %newfile% >nul 2>nul 
pause 
Verwandte Themen