[Batch] Anführungszeichen-Filter ist unmöglich?

zeddler

Neues Mitglied
hoi,
da anführungszeichen immer wieder probleme verursachen, so wollte ich einen filter basteln.
es sollte kurz & simpel sein und möglichst ein einzeiler.

1# stufe: erstmal was erkennen, das da irgendwas was ist.
wie könnte man diese "einfache" aufgabe umsetzen?

dieser befehl müsste ausführbar umgesetzt werden
Code:
if "==" (echo.do)

wenn man aber das erste zeichen variabel ist,...
Code:
set x="
if  %x%==" (echo.do)

dann gibt das problem wenn die variable leer ist
Code:
if ==" (echo.do)

leider klappt nicht mal der erste befehl, da " als systemzeichen immer verarbeitet/interprätiert werden.

doppelte "" funktionieren mit einer variable nicht,
da eine variable durch leerbleiben die zeichen anzahl asyncron macht.


es muss jetzt nicht unbedingt ein "if" befehl sein,
dieser dient nur zur veranschaulichung des problems.
 
Wenn du einen Filter basteln möchtest, wirst du an irgendeiner Stelle bestimmt find oder findstr benutzen wollen, oder? Hierfür sollte dir das weiterhelfen: https://www.robvanderwoude.com/escapechars.php
Ansonsten, um mich mal an dein Beispiel zu halten, hat bei mir (Windows 10) folgendes funktioniert:
Batch:
set x=""""
if %x%=="""" (echo hello)
pause
Warum genau das jetzt das erwünschte Ergebnis geliefert hat, ist mir allerdings ehrlicherweise schleierhaft ^^ Meine Hoffnung war, dass er doppelte Anführungszeichen innerhalb von Anführungszeichen als Escape für ein einzelnes intepretieren würde.
 
die variable
Code:
set x="
ist fest vorgegeben und kann nicht einfach geändert werden

prinzipiell gilt diese als unbekannt und könnte alles beinhalten, was die Kommandozeile ärgern kann.
ich kann nur die Länge auf 1 beschränken um so theoretisch jedes Zeichen einzeln zu scannen.

aber ich habe es hinbekommen:
Code:
set x="
if "%x%%x%"=="""" echo.do
ich kam einfach nie darauf, den asynchronen Zeichensatz
durch schlichtes verdoppeln des selben Wertes entgegen zu wirken.

das Endergebnis schaut jetzt so aus:
Code:
set xRAW=%*
if "%xRAW:~0,1%%xRAW:~0,1%"=="""" set xRAW=%xRAW:~1,-1%
damit kann ich die Anführungszeichen ganz gut weg filtern.

auch wenn die Eingabe %* ist, so dient diese nicht für den Eingabepfad von einer Datei,
sondern um Schalter, auf den nachfolgenden Positionen,
mit eigenen Eingabewerten, mit Leerzeichen... (ich habe Spaß)

bastel grad an dem Filter, um die Schalter zu finden und die Eingabewerte auszulesen...
 
Anführungszeichen haben eine spezielle Bedeutung in der Batch Syntax. Um zu verhindern dass Variablen bereits vor dem Parsen des Scriptcodes zum Wert aufgelöst werden, musst du mit verzögerter Variablenerweiterung arbeiten.
Etwa so:
Batch:
@echo off &setlocal
set "q=""
set /p "v=Enter a character: "

setlocal EnableDelayedExpansion
if "!v!"=="!q!" (echo !v! is quote) else echo !v! is no quote

pause
 
'SetLocal' scheint ja einige Probleme lösen.

nur verwende ich es nicht, da ich "globale" Variablen brauche.
und nach dem beenden von 'SetLocal' sind dessen variablen weg:
Code:
@echo off

set xGlobalVar=1
echo. && echo.[Global]
set x && echo.

SetLocal
set xLocalVar=1"
echo. && echo.[Local]
set x && echo.

EndLocal
echo. && echo.[Global]
set x && echo.

@pause

das hier ist nur ein Code-Schnipsel,
aber wie verhält sich 'SetLocal' bei verketteten Scripten & Programmen?

bzw. anders gefragt:
"unter welchen Umständen, sollte/muss 'SetLocal' aus-geschaltet werden?"

z.B. könnten externe fremd/Gast-Scripte selbst mit 'SetLocal' arbeiten
und es mir in einem ungünstigen Zeitpunkt abschalten.

gäbe es noch andere Probleme?
 
Zuletzt bearbeitet:
Batch ist eine der schwierigsten Sprachen die ich kenne. Nicht weil die Syntax kompliziert ist, sondern weil es fast unmöglich ist Code narrensicher zu schreiben. Das im Zusammenhang mit der Beschränktheit der Möglichkeiten, führt dazu, dass es völlig zu Recht tot ist und nicht mehr weiterentwickelt wird ¯\_(ツ)_/¯

Wenn du Scripte aus einem anderen Script per CALL aufrufst und du Variablen über die Scriptgrenzen (innerhalb eines cmd.exe Prozesses) behalten willst, dann lass das SETLOCAL hinter dem ECHO OFF weg. Das hat eher seinen Sinn für Debugging in einer CMD Console.

Ansonsten gilt: Definieren einer Variable ist sicher bei ausgeschalteter verzögerter Erweiterung, das Arbeiten mit dem Variablenwert ist sicher mit eingeschalteter verzögerter Erweiterung.
Variablen kannst du über die ENDLOCAL Grenze retten, indem du den Wert in derselben Kommandozeile abgreifst und neu zuweist.
Batch:
@echo off
set "q=""
set /p "v=Enter a character: "

setlocal EnableDelayedExpansion
if "!v!"=="!q!" (set "isQuote=yes") else set "isQuote=no"
endlocal &set "isQuote=%isQuote%"

echo %isQuote%

pause

Was da im Hintergrund abläuft, willst du aber lieber nicht wissen. SETLOCAL erzeugt eine Kopie der kompletten Umgebung. ENDLOCAL gibt diese wieder frei. Das ist weder ressourcenschonend noch performant. Batch eben ...
 
Zuletzt bearbeitet:
ja "Narrensicher" ist ein Unterfangen von mir,
damit verbrenne ich ganz gut meine Lebenszeit... ^^

mit "EndLocal && Set " ist ein interessanter Workaround für einzelne Befehle.
der wird notiert...

leider gibt es keine alternative zu BAT/CMD um erst mal einen Prozess zu starten*.
es ist halt der kleinste gemeinsame Nenner,
somit muss alles irgendwie durch Batch alles "durchgeprügelt" werden.
es ist eine Schande so was grundlegendes zu vernachlässigen!

*Narrensicher?:
Prozesse starten für DAU's muss via "Doppelklick" funktionieren...

VBS
fällt aus, da man es mit einem Befehl deaktivieren kann,
aber über selbiges nicht wieder aktivieren.

PowerShell
da haben die eine Chance vertan,
standesgemäß wird der Texteditor geöffnet * slow clap *
 
Was ist das für ein Anwendungsfall?

Warum nicht per CMD direkt Befehle an Powershell weitergeben oder eine ps1 ausführen?
pwsh.exe [-windowstyle hidden] "<skript.ps1>" ["<args>"] geht doch auch

Ich denke, ich verstehe dein Anliegen falsch.
 
um "per CMD direkt Befehle an Powershell weitergeben" muss ich CMD verwenden.
das ergibt als gegenargument keinen sinn.
interessant wäre es wie man das script ohne CMD startet.
es geht hier um ein "henne/ei"-problem

"oder eine ps1"
eine ps1 kann man nicht, ohne hilfsbefehl, von sich aus starten.
ich könnte die registryeinträge für den .ps1 dateityp ändern, aber das ist kein systemstandard.
"powershell.exe skript.ps1" ist wieder ein CMD-Kommando, das den powershell prozess startet...

ich habe das gefühl wir reden hier einander vorbei?

wie gesagt, was sich nicht via "doppelklick" oder ein generischen start-komando starten lässt,
läuft über "helper-app.exe script.ext"
 
Ich unterstelle nix, darum rede ich von mir ;) Ich hab vor 30 Jahren mit Batch und BASIC unter DOS begonnen. Heutzutage brache ich Scripting kaum noch, darum fällt es mir umso schwerer mich noch mit PS zu beschäftigen. Das ist mein Grund warum ich in Batch immer noch fitter bin als in PS. Nichtsdestotrotz - Wenn was funktionieren muss, nutze ich schon lange kein Batch mehr. Viel zu fehleranfällig. Und es gibt quasi nichts was man nicht innerhalb 5min auf der Manpage oder bei Google findet ...

standesgemäß wird der Texteditor geöffnet * slow clap *
launcher.bat:
@echo off

set args=%*
if not defined args powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '.\worker.ps1'" &goto :eof

set args=%args:"=\"%
set args=%args:`=``%
setlocal EnableDelayedExpansion
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '.\worker.ps1' !args!"
Wobei du die Aufbereitung der Argumente vermutlich nicht mal brauchst. Ich meine, wenn du einen User nicht beibringen kannst ein Script aus dem Kontextmenü auszuführen, dann kann der erst recht keine Argumente übergeben :ROFLMAO:

Egal ...
 
ich verwende Batch im kern auch immer weniger
und nutze es immer mehr nur noch als starter script.

früher (vor powershell)
habe ich mit "echo" zuerst ein VBScript geschrieben
und dann ausgeführt,
aber nicht ohne vorher zu prüfen das der scripting host deaktiviert wurde.
ihn zu aktivieren verlangt ja auch noch admin rechte... eine weitere hürde.

"Wobei du die Aufbereitung der Argumente vermutlich nicht mal brauchst. Ich meine, wenn du einen User nicht beibringen kannst ein Script aus dem Kontextmenü auszuführen, dann kann der erst recht keine Argumente übergeben"

das ist schwierig umzusetzen.
für den fall, das das script irgendwo landet, zu einer person, zu der ich keinen kontakt habe (internet)

dann kann ich entweder eine 10-seiten readme schreiben,
oder dafür sorgen dass es ein "narrensicheres", DAU-kompatibles script sich um alle sorgen kümmert. ;)

das ist arbeit die ich für die >imaginären< anderen mache,
für mich gibs auch google... alles selbst beigebracht... XD

da ich ja mein eigendliches problem schon in #3 selbst gelöst habe...

... so sitze ich gerade an meiner nächsten "unmöglichen" hardcore aufgebe: "dynamische variablen erzeugen"
%(A)+GruppenTag% geht schon, aber an verschachtelung %(A(B))% scheiter ich gerade noch.

ich bekomme schon die fertige variable %AB% , aber diese wird nicht mehr interprätiert und wird als text behandelt.

warscheinlich für den einen oder anderen absolut unnötig,
aber aus einer spontanen idee entsammt mein produktiver wahnsinn,
besonnders wenn es dann doch geht... XD

so, ich hänge hinter meinem zeitplan: "zähneputzen, p..."
ich werde mich heute an keinen weiteren argumentationsketten mehr beteidigen können... sry.
...chao.
 
Jedes CALL und das ECHO expandieren eine Variable bzw. halbieren die Anzahl verdoppelter Prozentzeichen.
Ist also so zu verstehen:
call call echo %%%%%%%a%1%%%%%%
call echo %%%b1%%%
echo %
c%

4711
 
ja, das geht ja.
aber diese "1" ist ein statisches objekt.
ich will das auch als variable differieren.

ich schaus mir morgen an... gn8.
 
Die Verdopplung der Prozentzeichen in jedem Expansionslevel musst du schon einhalten. Das ist halt dieser unsägliche, komplett unlesbare Nonsens mit Batch. Jede andere Sprache unterstützt Arrays für so etwas. Wenn du zigtausende Variablen definierst, vermüllst du dir das Environment. Das macht dein Script lahm (weil in Umgebungsvariablen ein Textvergleich gemacht werden muss, um die richtige zu finden) und klaut Arbeitsspeicher für jede andere Anwendung die parallel läuft.
 
mir war schon bewusst das es nicht richtig ist.
es war ehr als konzeptzeichnung zu verstehen.
das erste hatte ich ja lauffähig bekommen.
(dass dich das nicht gewundert hat. :D )
das zweite ist ja das was probleme verursacht
und ich noch nicht zum laufen bekommen habe.
 
das erste hatte ich ja lauffähig bekommen
Aber nicht so. Bzw. mit einem Ergebnis das definitiv nicht das ist was du wolltest.
Batch:
@echo off
set a=1
set b=2
echo %%a%%b%%
call echo %%a%%b%%
pause
Ergebnis
Code:
%a%b%
1b
Drücken Sie eine beliebige Taste . . .

Tja, was soll das nun sein? Doppelte oder dreifache Expansion? Musst du wissen.
call echo %%a%b%%%
oder
call call echo %%%%%%a%b%%%%%%%
 
Zurück
Oben Unten