Ich weiß nicht, was doco Sie für den Befehl set
gesehen haben, aber die Ausgabe von set /?
besagt eindeutig:
Mit der Option / P können Sie den Wert einer Variablen auf eine Eingabezeile festlegen, die vom Benutzer eingegeben wurde.
(meine Kursivschrift). Ich denke, dass set /p
seine Eingabe von der Konsole erhält, unabhängig davon, was Sie über die Standardeingabe eingeben möchten. Warum es nicht wartet, bin ich mir nicht sicher. echo xxx | set /p xx=
kann die Variable auch nicht setzen.
Wenn Sie jedoch eine Variable aus einer einzelnen Zeilendatei setzen möchten, können Sie einfach eine der folgenden verwenden:
%Vor%Das zweite ist das einfachste, aber es hilft nicht viel, wenn Sie die Ausgabe eines beliebigen Befehls abrufen möchten, aber Sie müssen es möglicherweise zuerst in eine Datei leiten.
Der erste erlaubt Ihnen, beliebige Befehle ohne temporäre Dateien auszuführen:
%Vor%Auf dieser Seite gibt es ein interessantes Snippet, das vorschlägt, dass es mit Kontexten zu tun hat:
Ok, ich habe selbst herausgefunden warum. Das liegt daran, dass
|
einen neuen Kontext erstellt, sodass die Variable den Rest des aktuellen Kontextes nicht erkennt. Beweis:
> set bar=
> echo aaa | (set /p bar= && set bar)
bar=aaa
> set bar
Environment variable bar not defined
obwohl ich es ablehne, die Richtigkeit dieser Schlussfolgerung zu kommentieren. Ich weiß nicht, welche Kontexte in diesem Sinne sind, ich mache nur auf Vollständigkeit aufmerksam.
Dies ist keine direkte Antwort auf die ursprüngliche Frage, die Why doesn't [..] work?
gefragt hat, aber diese Antwort kann nützlich sein für Leute, die versuchen, das logische Ergebnis von etwas wie dem zu erreichen:
Die normale Problemumgehung, zum Beispiel für den obigen Code, wäre:
%Vor%was die Arbeit perfekt macht, außer dass es eine neue Datei erstellt, die danach behandelt werden muss (zusätzlich zu der Tatsache, dass wir zusätzliche Schritte unternehmen müssen, um sicherzustellen, dass diese neue Datei eine bestehende Datei nicht überschreibt nicht erstellt oder nie beabsichtigt, zu ersetzen).
Obwohl es wahr ist, gibt es keine Möglichkeit , einen Dateistrom zu verwenden, um die Lücke zwischen beiden Seiten des Pipe |
-Operators zu überbrücken, sofern es sich um Umgebungsvariablen handelt, die sich unter Windows NT befinden Umgebung, und zur Verfügung gestellt der Datenträger, auf dem das Skript liegt, verwendet das NTFS-Dateisystem, kann man etwas viel eleganter als temporäre Dateien verwenden: alternative Datenströme
Sehen wir uns ein Beispiel an, das zeigt, wie man sie benutzen könnte:
%Vor% Hier steht %~nx0
für den Dateinamen (Basisname + Erweiterung) unserer Batch-Datei, der in Anführungszeichen eingeschlossen wird, falls er Leerzeichen enthält.
Hinweis: Wobei man stattdessen
%0
direkt (ohne Anführungszeichen) verwenden könnte Das aktuelle Skript.\%~nx0
ist besser zu verwalten, wenn Sie es jemals brauchen Sehen Sie sich den erweiterten Wert des Befehls an, während Sie Ihr Skript debuggen, vor allem, wenn der vollständige Pfad Ihres Skripts ziemlich lang ist.
Daher verweist ".\%~nx0":temp
auf einen alternativen Datenstrom (ADS) unseres eigenen Skripts namens temp
, zum Beispiel myscript.cmd:temp
, das wir erstellen (oder überschreiben) mit der Ausgabe des Befehls echo
. Da ADS sich genauso verhält wie der Standard-Stream einer Datei, sehen die Befehle echo
und set
keinen Unterschied.
Ein vollständiges Skript, das die Methode verwendet, könnte folgendermaßen aussehen:
%Vor% Hier, am Ende des Skripts, wird die Zeile type nul> %__self%:%__adsname
, die zu etwas wie type nul> ".\myscript.cmd":test.dat
erweitert werden könnte, verwendet, um den Inhalt des gerade verwendeten alternativen Datenstroms zu löschen. Obwohl dies die Größe des alternativen Datenstroms auf Null setzt, löscht er nicht (siehe unten).
Einige abschließende Anmerkungen:
Die meisten Befehle können alternative Datenströme nicht verstehen oder mit ihnen arbeiten, wenn sie als Quelldateien bereitgestellt werden. Dies bedeutet, dass die folgenden nicht verwendet werden können:
type
, z.B. %Code%
type myscript.cmd:data > myscript_data.txt
, z.B. %Code%
copy
, z.B. %Code%
copy myscript.cmd:data myscript_data.txt
/ move
, z.B. %Code%
move myscript.cmd:data myscript_data.txt
/ del
, z.B. %Code%
Tatsächlich ist es nur die Dateiumleitung, die alternative Datenströme unterstützt mit einer Ausnahme (was ich mir vorstellen kann): den Befehl erase
.
del myscript.cmd:data
eins) und das Bearbeiten / Ändern des Inhalts einer Datei wirkt sich nur auf den Standarddatenstrom aus. Dennoch haben wir je nach dem, was wir erreichen wollen, einige Optionen:
ren
beibehalten, nach dem die ursprüngliche Datei gelöscht werden kann. rename
. Sie können dann jedes Programm verwenden, um auf den Namen- (alternativen) Datenstrom einer Datei zuzugreifen, z. %Code%
Ich hoffe, das hilft!
Tags und Links pipe set cmd batch-file