Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit

Erzeugung von ESC,CR,LF und DEL mit reinem Batch

Anleitung Entwicklung Batch & Shell

Mitglied: jeb-the-batcher

jeb-the-batcher (Level 1) - Jetzt verbinden

06.12.2010, aktualisiert 07.12.2010, 15702 Aufrufe, 8 Kommentare, 1 Danke

Hallo an alle Batch Interessierten.

Zu erst, wozu das Ganze?

Weil ich Spaß daran habe mit Batch Sachen hinzubekommen die in jeder Programmiersprache vollkommen simpel sind,
und ich viel Zeit gebraucht habe all diese Sachen zu entwicklen (OK, der LF-Trick ist nicht von mir).

Wozu braucht man denn [DEL] oder ein [LF] Zeichen in einem Batchfile?

Um z.B. mit einem einzelnen echo über mehrere Zeilen eine Ausgabe machen zu können,
oder mit [DEL] bereits geschriebene Zeichen wieder zu löschen, z.B. für eine prozentuale Fortschrittsanzeige.

Jetzt erst mal der Code
01.
@echo off 
02.
setlocal EnableDelayedExpansion  
03.
call :CreateLF 
04.
call :CreateDEL_ESC 
05.
call :CreateCR 
06.
 
07.
echo Test1: The LineFeed!lf!This is in a new line 
08.
echo( 
09.
<nul set /p ".=Test2: The DEL removes a char, press a key #" 
10.
pause > nul 
11.
echo %DEL%X - changing of # with X 
12.
echo( 
13.
echo Test3: Print the ESC %ESC% 
14.
echo( 
15.
<nul set /p ".=Test4: ##########The CR can change a line, press a key" 
16.
pause > nul 
17.
echo !CR! It works ---  
18.
goto :eof 
19.
 
20.
::: LF should  be used only with DelayedExpansion 
21.
:CreateLF 
22.
set LF=^ 
23.
 
24.
 
25.
rem ** The two empty lines are neccessary, spaces are not allowed 
26.
set ^"NLF=^^^%lf%%lf%^%lf%%lf%^" 
27.
goto :eof 
28.
 
29.
::: DEL and ESC can be used  with and without DelayedExpansion 
30.
:CreateDEL_ESC 
31.
setlocal 
32.
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do ( 
33.
  ENDLOCAL 
34.
  set "DEL=%%a" 
35.
  set "ESC=%%b" 
36.
  goto :EOF 
37.
38.
goto :eof 
39.
 
40.
::: CR should  be used only with DelayedExpansion 
41.
:CreateCR 
42.
setlocal EnableDelayedExpansion EnableExtensions 
43.
set "X=." 
44.
for /L %%c in (1,1,13) DO set X=!X:~0,4094!!X:~0,4094! 
45.
 
46.
echo !X!  > %temp%\cr.tmp 
47.
echo\>> %temp%\cr.tmp 
48.
for /f "tokens=2 usebackq" %%a in ("%temp%\cr.tmp") do ( 
49.
   endlocal 
50.
   set cr=%%a 
51.
   rem set x= 
52.
   goto :eof 
53.
54.
goto :eof
Jetzt zu dem eigentlichem Teil, wie funktioniert das alles.

Das einfachste ist hierbei das LineFeed (LF).
Es wird durch eine multiline Caret ^ erzeugt mit zwei Leerzeilen.
Warum zwei? Weil das ^ eigentlich ein Escapezeichen für das folgende Zeichen ist als z.B. ^& am Zeilenende
wird aber das erste Zeilenende ignoriert und die nächste Zeile eingelesen, wenn da auch nur ein Zeilenende
gefunden wird, wird dieses "Escaped" damit ist kein Zeilenende mehr da und es wird eine weitere Zeile eingelesen,
die sollte dann leer sein, sonst wird der Inhalt an das <LF> drangehängt.
Jetzt kann natürlich der Einwand kommen, dass am Zeilenende nicht nur ein Linefeed steht sondern in der Windowswelt
eine Zeile mit <CR><LF> endet.
Das an dieser Stelle, dass <LF> genommen wird, statt des <CR> liegt daran, dass <CR> generell in dieser Phase nicht mehr existieren,
die wurden vom Parser entfernt.

Das <CR> wird daher über einen ganz anderen Weg erzeugt.
Es wird ein String erzeugt, der genau an der maximalen Länge für Strings liegt.
Dadurch kann bei dem echo !X! Befehl statt des normalen <CR><LF> Zeilenendes nur noch das <CR> ausgegeben werden.
Um an genau dieses dann zu gelangen wird noch ein weiteres <CR><LF> ausgegeben.
Die temporäre Datei enthält somit "....(ca 8000 Punkte)....<CR><CR><LF>"
Dann wird die Datei mit einem FOR /F eingelesen, dabei landet das einzelne <CR> im zweiten Token.
Da in der %%var Phase die <CR> nicht mehr entfernt werden, kann das <CR> erfolgreich einer Variablen zugewiesen werden.
Bei der Ausgabe klappt dann nur !CR!, weil in der anderen Variante %CR% das <CR> sofort wieder vom Parser entfernt wird.

Um das ESC und DEL zu erzeugen wird ein vollkommen anderer Weg verwendet.
Dazu wird der prompt Befehl genutzt, dieser erlaubt den Standard-Prompt mit $H$E umzustellen auf <DEL> und <ESC>.
Damit man allerdings dieses nicht nur auf der Kommandozeile sieht, sondern auch diesen in einem Batch auswerten kann,
wird echo on verwendet um auch innerhalb einer Batchausführung den Prompt zu sehen.
Damit man dann auch noch die Ausgabe abfangen kann wird der Teil innerhalb einer For-Loop ausgeführt.

Der einzige Teil der mir bei dem Ganzen noch nicht so recht gefällt, ist die Methode um <CR> zu erzeugen, da es praktisch auf
einen Bufferüberlauf angewiesen ist. Es ist also anzunehmen, dass dieses Verhalten vielleicht irgendwann mal entfernt wird,
oder es fehlschlägt, wenn z.B. die maximale Zeilenlänge von Microsoft geändert wird.

Hoffe es war nicht zu langweilig und es finden sich sinnvolle Anwendungen

jeb-the-batcher
Mitglied: jeb-the-batcher
06.01.2011 um 16:13 Uhr
Ich habe eine mir neue Methode von pieh-ejdsch angeschaut, wie er das CR erzeugt. Batch Prozent

Daraus habe ich jetzt eine neue elegante Variante gebastelt, die keinen Bufferoverlflow mehr braucht und auch ohne temporäre Datei auskommt.
Und das ganze ist auch noch schön kurz.

01.
::: CR should  be used only with DelayedExpansion 
02.
:CreateCR 
03.
for /F "usebackq" %%a in (`copy /Z "%~dpf0" nul`) DO ( 
04.
   set "cr=%%a" 
05.
06.
goto :eof
Und wie funktioniert's?
Der copy Befehl mit /Z erzeugt eine Ausgabe mit Fortschrittsanzeige 0% kopiert ... 100% kopiert.
Dabei wird der Fortschritt immer in eine Zeile geschrieben indem ein <CR> ausgegeben wird.
Und genau das hole ich mir, und damit ich bei der ganzen Aktion keine Datei real kopiere gebe ich als Quelle die eigene Batch-Datei an
und als Ziel NUL.

jeb - und wieder einen Schritt weiter
Bitte warten ..
Mitglied: rubberman
16.01.2011 um 01:06 Uhr
Hallo jeb.

Na das gefällt mir doch um Längen besser
Und dass das CR gleich das erste Token ist, ist ein Umstand der das ganze noch vereinfacht.

Wieder mal ist mir eine Nebensache nicht ganz klar (schließlich will man ja dazulernen).
Warum du usebackq nutzt, statt den 8.3-Namen der Batchdatei zu verwenden, leuchtet wegen möglicher Sonderzeichen ein. Warum allerdings "%~dpf0" statt "%~f0" ist mir suspekt. Unter welchen Umständen könnte letzteres fehlschlagen?

Grüße
rubberman
Bitte warten ..
Mitglied: jeb-the-batcher
16.01.2011 um 01:14 Uhr
Hallo rubberman,

ja da hat mal einer aufgepasst aber schön, dass doch jemand die Anleitungen liest.

Es ist natürlich vollkommen sinnlos %~dpf0 zu verwenden, statt direkt %~f0.
Aber dadurch kann man auch gut sehen, dass die Reihenfolge total egal ist, die einzelnen Pfadteile scheinen nur durch Flags aktiviert zu werden.
Denn %~pddpxffx0 ergibt auch nichts anderes als %~f0.

Grüße
jeb
Bitte warten ..
Mitglied: rubberman
16.01.2011 um 01:36 Uhr
Hallo jeb.

Zitat von jeb-the-batcher:
... aber schön, dass doch jemand die Anleitungen liest.
Oooch, knapp 1000 Hits in einem Monat ist doch mehr als nur "jemand".

Zitat von jeb-the-batcher:
Es ist natürlich vollkommen sinnlos %~dpf0 zu verwenden, statt direkt %~f0.
Und ich dachte schon mir wäre da was entgangen.

Schönen Abend noch
rubberman

<EDIT>
Das usebackq leuchtet doch nicht ein, schließlich verarbeitest du das Output eines Befehls und nicht die Datei selbst.
01.
for /f %%a in ('copy /z "%~f0" nul') do set "cr=%%a"
... sollte also ebenso funktionieren.
</EDIT>
Bitte warten ..
Mitglied: jeb-the-batcher
27.05.2011 um 20:51 Uhr
Da ist mir nach einem halben Jahr tatsächlich noch ein (schwerer) Fehler aufgefallen.

Die Erzeugung von <DEL> (oder auch <Backspace>,ASCII 0x08) ist nicht korrekt, denn meine Erklärung

Zitat von jeb-the-batcher:
Um das ESC und DEL zu erzeugen wird ein vollkommen anderer Weg verwendet.
Dazu wird der prompt Befehl genutzt, dieser erlaubt den Standard-Prompt mit $H$E umzustellen auf <DEL> und <ESC>.
Damit man allerdings dieses nicht nur auf der Kommandozeile sieht, sondern auch diesen in einem Batch auswerten kann,
wird echo on verwendet um auch innerhalb einer Batchausführung den Prompt zu sehen.
Damit man dann auch noch die Ausgabe abfangen kann wird der Teil innerhalb einer For-Loop ausgeführt.

Ist an der Stelle von $H nicht richtig, denn $H ist kein einzelnes <Backspace> sondern in Wirklichkeit eine Kombination aus
<Backspace><Space><Backspace>, sprich in der DEL-Variabeln sind auch immer drei Zeichen gelandet.

Aber wenigstens ist die Korrektur recht einfach, ein zusätzliches Space bei delims reicht, somit ergibt sich
01.
:CreateDEL_ESC 
02.
:: Creates two variables with one character DEL=Ascii-08 and ESC=Ascii-27 
03.
:: DEL and ESC can be used  with and without DelayedExpansion 
04.
:: @attention $H produce a <BS><space><BS>, so we need # and <space> as delims 
05.
setlocal 
06.
for /F "tokens=1,2 delims=# " %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do ( 
07.
  ENDLOCAL 
08.
  set "DEL=%%a" 
09.
  set "ESC=%%b" 
10.
  goto :EOF 
11.
12.
goto :eof
jeb
Bitte warten ..
Mitglied: rubberman
30.05.2011 um 01:14 Uhr
Hallo jeb,

das funktioniert bei mir so nicht. Ist auch unlogisch, denn durch Space als zusätzlichen Delimiter hast du nun im 1. und im 2. Token ein Backspace.
What about:
for /F "tokens=2,3" %%a in ('"prompt $H$S$E$S & echo on & for %%b in (1) do rem"') do (
Grüße
rubberman
Bitte warten ..
Mitglied: pieh-ejdsch
26.08.2012 um 11:21 Uhr
moin,

Das Del aus <del><space><del> besteht ist vllt nur deswegen, weil ein Einzelnes Del im Anschluss Keinen Rückschritt macht. Wenn also hinter einem Einzelnen Del kein Zeichen ist erfolgt auch kein Rückschritt.

Das SpaceZeichen ($S) hinter dem Prompt Befehl in der For-Anweisung leuchtet ja noch ein.
Aber warum wird dort ein echo on geschalten? In der Anweisung einer Forschleife ist immer ein Echo on geschalten.
wie cmd /c im Gegensatz zu cmd /q /c.

Ich hab mir jetzt die Zähne verbissen, weil ich ein = in ein <nul set /p "==" wollte. Mal sehen das löse ich noch anders.

Gruß Phil
Bitte warten ..
Mitglied: rubberman
26.08.2012 um 13:57 Uhr
Hallo PH,

du hast recht, das ECHO ON ist unnötig.

Zu deinem Problem - teste mal:
01.
for /f %%a in ('"prompt $H &for %%b in (1) do rem"') do set "BS=%%a" 
02.
set /p "=.%BS%="
Der Nachteil ist selbstverständlich, dass Punkt und Backspace bei Umleitung in eine Datei mit umgeleitet würden ...

Grüße
rubberman
Bitte warten ..
Neuester Wissensbeitrag
Ähnliche Inhalte
Batch & Shell
Batch-Variable nach Stichworten aus TXT Datei durchsuchen (3)

Frage von Markus5579 zum Thema Batch & Shell ...

Batch & Shell
Dateinamen nach Zeichnen abschneiden - Batch-Shell (9)

Frage von cberndt zum Thema Batch & Shell ...

Batch & Shell
CMD Verschlüsslung ( Batch ) (11)

Frage von clragon zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
Windows Userverwaltung
Ausgeschiedene Mitarbeiter im Unternehmen - was tun mit den AD Konten? (33)

Frage von patz223 zum Thema Windows Userverwaltung ...

LAN, WAN, Wireless
FritzBox, zwei Server, verschiedene Netze (21)

Frage von DavidGl zum Thema LAN, WAN, Wireless ...

Viren und Trojaner
Aufgepasst: Neue Ransomware Goldeneye verbreitet sich rasant (20)

Link von Penny.Cilin zum Thema Viren und Trojaner ...

Windows Netzwerk
Windows 10 RDP geht nicht (18)

Frage von Fiasko zum Thema Windows Netzwerk ...