jeb-the-batcher
Goto Top

Parameter SICHER einer Variable zuweisen?

Ist es generell möglich einen Parameter (%1) einer Variablen zuzuweisen?

Nein. Die Antwort ist nicht trivial!

Bereits bei meinem ersten Beispiel finde ich keine Lösung.

param.bat one^&two"&three

Denn diese Varianten schlagen alle fehl

set var=%1
set "var=%1"  
set "var=%~1"  

Das Problem ist offensichtlich, die Verarbeitung der Sonderzeichen.
Die stellen kein Problem mehr da, wenn man den Inhalt erst mal in einer Variablen hat, aber wie bekommt man das erst mal hin?

Meine Versuche mit
set "var=!1"
for %%a in (dumm) do set var=%%1
call set var=%%1
scheitern leider auch alle.

Bei DelayedExpansion wird gar nicht aufgelöst, ebenso wenig bei for-loop variabeln.
Der Versuch mit call verschiebt das Problem einfach nur in den zweiten Parser-Lauf, dort wird beim Auffinden von Sonderzeichen gleich die Bearbetung gestoppt, das ist zwar noch besser als die anderen Varianten, aber scheinbar auch kein Lösungsansatz.

Aber vielleicht hat ja noch jemand eine bessere Idee.

Content-ID: 152411

Url: https://administrator.de/contentid/152411

Ausgedruckt am: 08.11.2024 um 21:11 Uhr

miniversum
miniversum 05.10.2010 um 18:42:11 Uhr
Goto Top
Schildere doch mal den konkreten Anwendungsfall für den du das benötigst?
so ohne es auszuprobieren würd ich jetzt aber einfach mal behaupten das die "& kombination ein Problem bereitet.
jeb-the-batcher
jeb-the-batcher 05.10.2010 um 19:08:05 Uhr
Goto Top
Hallo miniversum,

ich habe keine konkreten Fall, es geht mir darum, ob es prinzipiell möglich ist.
Und schliesslich betrifft es ja auch alle Funktionen innerhalb eines Batchfiles bei dem Strings als Parameter übergeben werden sollen.

call :stringLength result "%myString%"



Die "& Komibination alleine kann man lösen.

param.bat two"&three
set var=%~1

Auch die Kombination one^&two ist für sich alleine kein Problem

param.bat one^&two
set "var=%~1"  

Aber bereits die Entscheidung welche Variante man wählen muss, ist schon nicht offensichtlich.
miniversum
miniversum 05.10.2010 um 19:45:13 Uhr
Goto Top
Ok dann haben wir zwei unterschiedliche Auffassungen. Den ich sehe keinen Sinn in so einer Konstruktion und daher ist eine rein theoretische Lösung für ein nicht vorhandenes, nur rein erdachtes Problem es mit einfach nicht wert darüber nachzudenken, sorry. Sollte ich ein ähnliches Problem in der Praxis wirklich haben würde ich eine speziell dafür angepaste Lösung verwenden die die vorhandene Umgebung berücksichtigt. Ich hätte dann dann auch kein Problem auf eine andere Sprache umzusteigen.
pieh-ejdsch
pieh-ejdsch 05.10.2010 um 20:44:48 Uhr
Goto Top
nun entweder ich trenne meine Parameter Klar auf oder ich fasse diese zusammen mit Umschliessenden Anführungszeichen, wenn Leer- & SonderZeichen enthalten sind.

Gruß Phil
jeb-the-batcher
jeb-the-batcher 06.10.2010 um 09:03:12 Uhr
Goto Top
Nun der Sinn ist, zu verstehen wie man Programme sicher schreibt.

Wenn ich z.B. eine Funktion schreibe, dann überlege ich auch ob diese alle Eingaben verkraftet oder in bestimmten Fällen ein falsches Ergebnis liefert oder sogar komplett abstürzt.
Und wenn ich eine Funktion String_Length aufrufe erwarte ich ein korrektes Ergebnis, und nicht ein: "Bei diesem oder jenem String funktioniert das nicht".

Sprich bei Batch möchte ich auch sicher gehen, dass es egal ist welche Parameter übergeben werden, das Batchfile sollte damit zurecht kommen.
pieh-ejdsch
pieh-ejdsch 06.10.2010 um 20:33:22 Uhr
Goto Top
Nun der Sinn ist, zu verstehen wie man Programme sicher schreibt.

aber grundlegend gibst Du doch dem Bachprogramm als Parameter mit was auch klar unterschieden werden kann.

  • Optionen mit einem führenden / slash
  • Pfad\Dateinamen mit SonderZeichen in Anführungszeichen

da die (Umschliessenden) Anführungszeichen Sonder - Sonderzeichen sind, sollten diese nur zum ParameterBegrenzen benutzt werden wenn die Restlichen Sonderzeichen für welche eines Dateinamens stehen.

für solche ProblemZeichen kannst Du doch den Befehl
SET /P var=Bitte gib die zu bearbeitende Zeichenfolge ein
oder
SET /P "var=Bitte gib die zu bearbeitende Zeichenfolge ein & drueck Eingabe!" 
in den Batch einbauen - mit diesem wiederum kannst Du gefahrlos weiterarbeiten.

Ob Du nun diese Verzwickte Zeichenfolge in die erste oder zweite CMDZeile hackelst macht es doch nicht unbedingt schwieriger.

Gruß Phil
jeb-the-batcher
jeb-the-batcher 06.10.2010 um 21:00:42 Uhr
Goto Top
Das mit dem set /p ist schon klar.

Aber wenn ich ein batch-File schreibe, dann habe ich vielleicht keinen Einfluss darauf, was jemand an Parametern übergibt.

Zumindestens sollte das Programm erkennen können, dass die Parameter nicht dem erforderlichen Format entsprechen.
pieh-ejdsch
pieh-ejdsch 06.10.2010 um 21:44:14 Uhr
Goto Top
da gibst Du dem Batch eine Aussagekräftige Hilfe mit, welche der Anwender im Zweifelsfall als Dokumentation durchlesen kann.
so hab ich es bei Script Programmcode auch gemacht

Ich weis .... Version 1.9 ist auch schon fast fertig - coming soon

PS: Deine Originale ParameterÜbergabe übersteht es auch! (wenigstens mit einer Fehlermeldung)

Gruß Phil
rubberman
rubberman 08.10.2010 um 23:49:41 Uhr
Goto Top
Hallo jeb,

habe keinerlei Lösung finden können. Der einzige Befehl, der deinen Beispielparameter überhaupt als literalen Ausdruck interpretiert, scheint REM zu sein. Bei eingeschaltetem Prompt bekomme ich
>rem one&two"&three
angezeigt.
Wie das dabei helfen könnte, den Spaß in eine Umgebungsvariable zu packen ist mir allerdings selbst schleierhaft.

Grüße
rubberman
jeb-the-batcher
jeb-the-batcher 09.10.2010 um 09:08:00 Uhr
Goto Top
Ich habe zuerst in der Richtung gesucht mit call set "var=%%1" und call call set %%caret%%"var2=%%1"
und dann aus var und var2 die Lösung zusammen zu basteln.
Klappt aber auch nicht mit allen Strings
"&"^&

Den REM Befehl, habe ich dann auch als Lösung gefunden.
Der Trick besteht darin, die Ausgabe in eine Datei zu redirecten.
Denn aus einer Datei kann man problemlos zerstörungsfrei lesen.

Das Problem ist, dass man die Debugausgabe nicht direkt umleiten kann.
>debug.txt rem %1 
Klappt also nicht

Dafür klappt dies
echo on
call :func > debug.txt
goto :eof
:func
rem This %1
goto :eof

Nur leider kann man in der Funktion nicht mehr auf %1 der Batch zugreifen.

Das ganze klappt auch nicht mit einer umgeleiteten For-Schleife, aber mit zweien face-smile

@echo off


setlocal DisableDelayedExpansion
set "prompt=X"  
for %%a in (1 ) do (
	@echo on
	for %%b in (4) do (
		rem #%1#
	) 
) > XY.txt
@echo off
for /F "delims=" %%a in (xy.txt) DO (  
  set "param=%%a"  
)
setlocal EnableDelayedExpansion
rem set param=!param:~7,-4!
echo param='!param!'  
@goto :eof

Die #%1# ist dazu da, mögliche Multiline Kombinationen zu unterdrücken.
Denn auch in einem Rem wird ^ ausgewertet, allerdings nur wenn es am ersten Token (nach dem REM) hängt
rem This is a remark^
rem This_is_a_multiline^
rem "This is also a multiline"^  

jeb
rubberman
rubberman 09.10.2010 um 15:47:52 Uhr
Goto Top
Hallo jeb.

Dass man das ganze in eine Datei umleiten sollte, war mir irgendwie schon klar. Anfangs dachte ich dass mir irgend ein sinnentfremdeter Befehl (wie TYPE %1 o.ä.) eine brauchbare Fehlermeldung ausspuckt.
REM umleiten zu wollen habe ich allerdings gleich wieder verworfen, da REM keinen Stream zu StdOut oder StdErr sendet. Um so mehr überrascht mich, dass es über Umwege doch funktioniert.

Grüße
rubberman