Wenn Sie eine Batch-Datei ausführen, wird jede Zeile oder jeder Zeilenblock (in Klammern eingeschlossene Zeilen) zuerst analysiert und dann ausgeführt. Während des Parsens werden die Leseoperationen für die Variablen durch den Wert innerhalb der Variablen ersetzt, bevor die Befehle ausgeführt werden. Wenn also in einer Zeile/einem Block ein Variablenwert geändert wird, können Sie diesen geänderten Wert nicht abrufen, da der Parser die Leseoperation mit dem Wert in der Variablen entfernt hat, bevor die Änderung vorgenommen wurde.
Also, Ihr Code
set p=notepad.exe&%p%
wird analysiert und umgewandelt
set p=notepad.exe&
wo die Leseoperation %p%
erhalten hat sich mit dem Wert der Variablen ersetzt worden (die Probe die Variable annimmt, ist leer). Dann wird diese analysierte Zeile ausgeführt.
Warum funktioniert es das zweite Mal? Da im vorherigen Lauf die Variable festgelegt wurde und, wenn sie nicht zurückgesetzt wurde, der Parser im zweiten Lauf die Ersetzung durchführt, enthält die Variable einen Wert, der in der Zeile ersetzt werden soll.
Um zu sehen, dass dies ein Parse vor Verhalten ausführen, können Sie Ihre Linie zu
set p=notepad.exe&set p
ändern können, die ist, die Variable gesetzt und die Umwelt Inhalt Dump (Variablen mit p beginnen) und Sie werden sehen, dass Die Variable wurde auf notepad.exe
gesetzt. Da diese Zeile keine Leseoperation für die Variable enthält, funktioniert alles wie erwartet.
Wie lösen Sie Ihr Problem?Es gibt einige Optionen
Expansion Verzögerte
Wenn verzögerte Erweiterung aktiviert ist, liest die Syntax auf Variable geändert werden kann, bei Bedarf, %var%
-!var!
, was anzeigt, an den Parser, dass die Substitution auf der Leseoperation Bedürfnisse, bis die Befehlsausführung verzögert werden
setlocal enabledelayedexpansion
set p=notepad.exe&!p!
das gleiche Verhalten aktiviert werden kann, wenn der Befehlsprozessor mit /v:on
genannt wird 210
cmd /v:on /c "set p=notepad.exe&!p!"
Kraft einen zweiten Parse auf dem Befehl
Dies verwendet die call
Befehl ein zweites Parse auf der Linie
set p=notepad.exe&call %%p%%
Die erste Standard zu zwingen Parse die wörtliche %%p%%
mit wörtlichen ersetzt %p%
(%%
ist ein Escape-Prozentzeichen) ohne Variablenersatz zu tun, und wenn der Befehl call
ausgeführt wird, wird die Zeile erneut analysiert, also das Literal %p%
wird als gelesene Variable interpretiert und durch den Wert in der Variablen ersetzt
Was zu verwenden? Es kommt darauf an. Verzögerte Expansion Lösung hat bessere Ausführungszeiten, die call
Lösung (call
Befehl macht viel mehr Arbeit), aber wenn verzögerte Expansion aktiviert ist Ausrufezeichen (!
) in den Daten enthalten werden ein Problem, das richtig behandelt werden muss.
Wenn Sie einen exe.exeption Editor oder eine Datei öffnen, können Sie es direkt in einer Zeile tun, was genau wollen Sie mit dieser Variable? – ZAT
@ZAT Es ist nur ein Beispiel. Mein Zweck ist es, eine komplizierte Batch-Datei in eine einzige Zeile zu konvertieren. Der gesamte Code wird konvertiert, außer dass eine Variable wie oben definiert wird. Ich möchte die Batch-Datei nicht direkt ausführen. –
Wenn Sie komplexen Code in Variablen speichern, interessiert Sie vielleicht [Batch "Makros" mit Argumenten] (http://www.dostips.com/forum/viewtopic.php?f=3&t=1827) – dbenham