Mini-Skript-Anfrage

German support forum

Moderators: white, Hacker, Stefan2

Post Reply
Dauer-TC-ler
Junior Member
Junior Member
Posts: 53
Joined: 2015-03-14, 17:49 UTC

Mini-Skript-Anfrage

Post by *Dauer-TC-ler »

Hallo zusammen!

Das ist jetzt zwar keine direkte TC-Frage, aber ich weiß, daß hier profunde Skripter unterwegs sind - ich hoffe um Nachsicht :-)

Ich würde gern einen, an ein Batchskript übergebenen Parameter (%1) innerhalb der Skriptes ändern, also so, daß der neue Wert weiterhin für den Rest des Skriptes mit dem ursprünglichen Parameter-Platzhalter (%1) verwendet werden kann.

Aufruf, beispielsweise: Test.bat alt

Code: Select all

@echo off
cls
set %1=neu
echo %1
pause
...sollte dann "neu" ausgeben - tut es aber nicht, %1 hat weiterhin den Wert "alt".
Hab schon alle möglichen doppel-% und "" und == und ^ probiert, geht aber nichts.

Hintergrund:
Das Übergabe-Programm für die Batch kann einen bestimmten Parameter (von möglichen weiteren) für %1 nur fehlerhaft (Schreibweise) erzeugen und übergeben. Deshalb muß dieser Wert vor dem weiteren Einsatz im Skript erst korrigiert werden. Nicht CHCP-korrigierfähig, da Normaltext.

Vermutlich sehr einfache Sache, aber irgendwie stehe ich damit auf dem Schlauch
und wäre über Hilfe dankbar: Wie heißt die set...-Zeile richtig?

Grüße,
Dauer-TC-ler
User avatar
karlchen
Power Member
Power Member
Posts: 4601
Joined: 2003-02-06, 22:23 UTC
Location: Germany

Re: Mini-Skript-Anfrage

Post by *karlchen »

Hallo, Dauer-TC-ler.

%1 ist und bleibt das erste Argument auf der Kommandozeile. %1 selbst kann daher nicht verändert werden.
Der Weg geht also über eine zweite, tatsächlich veränderbare Variable.

Code: Select all

@echo off
SETLOCAL EnableDelayedExpansion
cls
set KORREKT=%1
REM /i compares case insensitive
if /i "%1"=="alt" set KORREKT=neu
echo !KORREKT!
pause
ENDLOCAL
Hoffe das funktioniert so.

Grüße,
Karl
Last edited by karlchen on 2021-11-30, 21:13 UTC, edited 2 times in total.
MX Linux 21.3 64-bit xfce, Total Commander 10.52 64-bit
The people of Alderaan keep on bravely fighting back the clone warriors sent out by the unscrupulous Sith Lord Palpatine.
The Prophet's Song
User avatar
Dalai
Power Member
Power Member
Posts: 9364
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Re: Mini-Skript-Anfrage

Post by *Dalai »

Positionsparameter von %0 bis %9 sind fest in ihrem Inhalt, d.h. nicht änderbar. Die einzige Änderung, die man in Bezug auf Positionsparameter machen kann, ist deren Position, d.h. Parameter %3 wird zu %2 und %2 wird zu %1 mittels des Befehls shift (siehe shift /? auf einer CMD). Positionsparameter %0 ist aber selbst dadurch nicht beeinflussbar, weil %0 immer das Skript selbst angibt.

Aber die Sache ist ganz einfach: Speichere den Positionsparameter in eine Variable und nutze diese Variable im restlichen Skript:

Code: Select all

@echo off
set "variable=%~1"
if "%variable%"=="irgendein inhalt" set "variable=irgendein anderer inhalt"
echo %variable%
Nur für den Fall, dass es noch nicht bekannt ist:
  • %~1 gibt den Inhalt von %1 an, entfernt aber die äußeren Anführungszeichen, sofern vorhanden
  • Das Zuweisen von Variablen mit set "var=inhalt" stellt sicher, dass eventuell vorhandene Steuerzeichen in "inhalt" nicht zum Abbruch des Skripts oder seltsamem Verhalten wegen Syntaxfehlern führen. Bei Klammern passiert das sehr gern mal, und jeder, der z.B. %ProgramFiles(x86)% schonmal zugewiesen hat, weiß wie nervig das sein kann. Die Positionierung der Anführungszeichen vor dem Namen der Variable stellt außerdem sicher, dass keine Anführungszeichen im Inhalt enthalten sind, wie es bei set var="inhalt" der Fall wäre. Das macht es einfacher, die Anführungszeichen später bei Verwendung der Variable zu ergänzen (Ausgabe mit echo, Zusammenbau eines Strings usw).
Wobei mich mal interessieren würde, welche Ersetzung du da machen willst/musst...

Regards
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
Dauer-TC-ler
Junior Member
Junior Member
Posts: 53
Joined: 2015-03-14, 17:49 UTC

Re: Mini-Skript-Anfrage

Post by *Dauer-TC-ler »

@karlchen
Danke für die Info, jedoch hatte ich diese Lösung auch schon, wäre aber für den weiteren Gesamtverlauf doch recht umständlich. Müßte dann Skript-weit alle %1 in "Schlagmichtot=" abändern - Spaß beiseite: "A=" ginge natürlich auch. Ich wollte einfach nur wissen, ob... und das hast Du mir ja definitiv klar beantwortet. Jetzt kommen also Workarounds zu Einsatz.

@Dalai
Genauso Danke für die prinzipiell gleiche Antwort: Ich glaub es definitiv. Deine weiteren Ausführungen sind mir jüngst auf der Websuche bzgl. des Problems auch schon in etwa begegnet.

Wofür ich das brauche?

Da gibt es das Uralt-Rrogramm RemoteKeys, das ich wegen dieser genialen Menü-Tafel-Form für einen bestimmten Zweck (Multimonitor-Umgebung) benötige. Ein Nachbau in AHK wäre zwar möglich, jedoch mit erheblichem Aufwand verbunden, und trotzdem niemals so elegant und auch noch so komfortabel programmierbar wie RK. Dummerweise übergibt RK aus mir unerfindlichen Gründen beim Start einer Batch in einem der Fälle (RK-Knöpfe) den Parameter "+" (Pluszeichen) nur so: "{+" Also geschweifte Klammer und Pluszeichen. Alle anderen Übergaben, auch die abgefahrensten Sonderzeichen, funzen richtig. Leider ist RK von Detlev Schäfer schon lange (2003) eingestellt worden und es gibt auch keinen Support mehr.
Vermutlich ein Bug im PRG.

Mal schauen. Evtl. löse ich das so, daß ich beim entsprechenden RK-Befehl erst eine vorgeschaltete Datei erstelle, die dann den richtigen Parameter "+" enthält (gemacht bekommt ;-) ) und die dann den eigentlichen Aufruf der Hauptbatch stellvertretend für RK übernimmt. Vorteil: %1 bleibt in der Hauptbatch weiterhin und durchgehend das, was es ist. Wird dort derart häufig verwendet, so daß ich mit (späterem) Lesen oder Ändern nicht so verwirrt werde. Und es kann einfach nicht angehen, daß wegen 1 blödsinnigen Sonderling alle anderen umstellen sollten...

Gut Klick alleweil!
Dauer-TC-ler
User avatar
Dalai
Power Member
Power Member
Posts: 9364
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Re: Mini-Skript-Anfrage

Post by *Dalai »

2Dauer-TC-ler
Könnte es sein, dass in dem in RemoteKeys hinterlegten Kommando zusätzliche Zeichen enthalten sind? Welches Kommando verwendest du denn zum Starten einer Batchdatei? Hab mir das Programm grad mal angeschaut und hab dieses Kommando auf einen Button gepackt:

Code: Select all

{/APP.OPEN H:\RK.cmd,foo bar blub}
Die dort hinterlegte Batch

Code: Select all

@echo off

echo %*

echo.
pause
gibt die erwarteten Parameter "foo bar blub" aus. Gleiches passiert mit

Code: Select all

{/APP.OPEN cmd.exe,/C H:\RK.cmd foo bar blub}
Übergibst du da noch mehr bzw. andere Parameter oder startest du die Batch per Tastenkombination?

Grüße
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
Dauer-TC-ler
Junior Member
Junior Member
Posts: 53
Joined: 2015-03-14, 17:49 UTC

Re: Mini-Skript-Anfrage

Post by *Dauer-TC-ler »

Ich hab es jetzt ganz elegant so gelöst:

Code: Select all

:...
REM Hauptbatch.bat läuft bereits, 374 Zeilen, mute ich hier jetzt keinem zu... 
REM Sie wird per RemoteKeys je nach Anforderung mit mehreren oder auch keinem Parameter aufgerufen.
REM Falls das "+" ( zunächst fälschlich als "{+" ) beauftragt ist, dann immer als %3 
:...

:NamePfadClass
REM RemoteKeys gibt als 3. Parameter "+" immer mit "{+" aus. 
REM Deshalb in nur diesem Fall Korektur über eine andere Batch, 
REM die dann die Haupbatch korrekt mit "+" als 3. Parameter erneut startet. 
if not %3=={+ goto ClassStart
Rep+.bat %1 %2

:ClassStart
:...
REM ...und weiter geht´s mit der Hauptbatch
:...
Inhalt der Rep+.bat ist dann nur 1 Zeile:

Code: Select all

Hauptbatch.bat %1 %2 +
Die ursprünglichen %1 %2 werden dabei nur durchgereicht.
Auf dem Umweg über eine 2. Batch übergebe ich somit den 3. Parameter korrekt,
und habe dann weiterhin meine Standard-Parameter-Bezeichnungen ohne komische Umetikettierung.

@Dalai

Bist ja ein echter Kenner, und noch vom alten Schlag - Bravo ;-)

Der RK-Aufruf per Knopf könnte mit 3 Parametern z.B. so aussehen:

Code: Select all

{/APP.OPEN Hauptbatch.bat, Serie1, h:\HDD-5, !}
Das kommt dann korrekt mit ! als %3.
Aber das da:

Code: Select all

{/APP.OPEN Hauptbatch.bat, Serie1, h:\HDD-5, +}
kommt eben so: {+
weiß der Geier warum. Hast Du eine Idee, warum?
Könnte das "+" in RK irgendwie eine Skript-Klammer als eine Art Unterroutine auslösen?
User avatar
Dalai
Power Member
Power Member
Posts: 9364
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Re: Mini-Skript-Anfrage

Post by *Dalai »

Mit einem Pluszeichen als Parameter kann ich das Phänomen/Problem nachvollziehen (hätte ich selbst drauf kommen können/sollen). Es sieht tatsächlich so aus, dass RemoteKeys das Pluszeichen als spezielles Zeichen sieht und diverse Dinge damit tut. Einerseits erfolgt eine Ersetzung durch "{+" und andererseits verschwinden alle nach dem Pluszeichen folgenden Parameter. Ein Kommando wie

Code: Select all

{/APP.OPEN H:\RK.cmd,"foo bar + blub"}
führt zur Ausgabe

Code: Select all

"foo bar {+
Ja, tatsächlich nur mit dem einleitenden Anführungszeichen. Daher glaube ich, dass das + eine Sonderbedeutung hat. Deine Ersetzung funktioniert daher auch nur, wenn das Plus der letzte Parameter ist.

Leider hatte ich keinen Erfolg mit verschiedenen Escapings des Pluszeichens, sei es per Backslash, Verdoppelung, oder Einfassen in Anführungszeichen oder geschweifte Klammern. Auch die Programmhilfe gibt nicht wirklich etwas dazu her.

Ob das ein Bug ist oder nicht, kann ich nicht beurteilen. Möglich ist es. Vielleicht wäre es besser, statt des Plus ein anderes Zeichen zu benutzen.

Noch ein Tipp. Sowas wie

Code: Select all

if not %3=={+ goto ClassStart
geht kaputt, wenn kein dritter Positionsparameter angegeben wurde. Meine Empfehlung ist daher, immer Anführungszeichen in Vergleichen zu benutzen (bzw. generell bei Verwendung von Variablen).

Grüße
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
Dauer-TC-ler
Junior Member
Junior Member
Posts: 53
Joined: 2015-03-14, 17:49 UTC

Re: Mini-Skript-Anfrage

Post by *Dauer-TC-ler »

Vielleicht wäre es besser, statt des Plus ein anderes Zeichen zu benutzen.
Es geht hierbei um Datei-Klassifikation, -Kennzeichnung, -Markierung, -Zuordnung und dgl., wobei das jeweilige Zeichen hierfür meist am Ende des Dateinamens steht, in einem Fall auch in der Mitte. Anhand dieser Markierungen wird per -was auch immer (RK, AHK, Batch, manuell) - weiterverarbeitet, und diese Markierung ergebnisorientiert auch entsprechend verändert oder gelöscht.

Und jetzt der springende Punkt: Es stehen hierfür grad mal 5 Stück, nämlich = + ! $ # zur Verfügung, also welche der DOS-Code als normal und nicht funktional behandelt. Alle anderen Zeichen/Buchstaben sind für normales Vorkommen in Dateinamen reserviert. Oder andersrum ausgedrückt, ich muß peinlich genau darauf achten, daß diese 5 Marker nicht in Dateinamen vorkommen. Fazit: Die Auswahl an Markern ist nicht gerade gewaltig, so daß ich keinen davon gerne opfern will. Und Datei-Metadaten sind für Skripte meines Wissens nach bömische Dörfer. Aber es funktioniert jetzt ja mit dem guten + voll und ganz.
Deine Ersetzung funktioniert daher auch nur, wenn das Plus der letzte Parameter ist.
Danke für diese Entdeckung, denn ein 4. Parameter ist bereits im Gespräch. Also das + immer zuletzt :-)
Noch ein Tipp. Sowas wie
if not %3=={+ goto ClassStart
geht kaputt, wenn kein dritter Positionsparameter angegeben wurde. Meine Empfehlung ist daher, immer Anführungszeichen in Vergleichen zu benutzen (bzw. generell bei Verwendung von Variablen).
Prinzipiell ja, aber in diesem Fall werden eingangs der Hauptbatch alle denkbaren Parameter-Situationen bis hin zu einem Menü mit Auswahlpunkten bereits im Vorfeld abgefangen und jeweils zu den Abschnitten/Sprungzielen geschickt, wo speziell für diese die Medizin bereitsteht. Will heißen, zu dem für dieses Problem zuständigen Facharzt ":NamePfadClass" werden nur diejenigen hingeschickt, die 3 Parameter mit den oben erwähnten Markern haben. Andere kommen nie hier vorbei.

Grüße,
Dauer-TC-ler
NotNull
Senior Member
Senior Member
Posts: 266
Joined: 2019-11-25, 20:43 UTC
Location: NL

Re: Mini-Skript-Anfrage

Post by *NotNull »

karlchen wrote: 2021-11-30, 21:07 UTC %1 ist und bleibt das erste Argument auf der Kommandozeile. %1 selbst kann daher nicht verändert werden.
Dalai wrote: 2021-11-30, 21:08 UTC Positionsparameter von %0 bis %9 sind fest in ihrem Inhalt, d.h. nicht änderbar.
Nicht unbedingt ... :

Code: Select all

@echo off & setlocal

Echo Vorher
echo 0 = %0
echo 1 = %1


call :ROUTINE geandert
goto :EOF



:ROUTINE
	Echo Nachher
	echo 0 = %0
	echo 1 = %1
goto :EOF



Output:

Code: Select all

T:\>parmtest.cmd something
Vorher
0 = parmtest.cmd
1 = something
Nachher
0 = :ROUTINE
1 = geandert


Und damit soll foldendes wahrscheinlich gehen (ohne der Original code gesehen zu haben ist das nicht sicher weil CALL und GOTO statements Probleme machen können)

Original:

Code: Select all

@echo off & setlocal
echo do something 
echo parm1=%1
echo parm2=%2
echo parm3=%3

Neu:

Code: Select all

@echo off & setlocal

   set "PARM3=%3"
:: REmove possible {'s from parameter 3
   set "PARM3=%PARM3:{=%"

   Call :ROUTINE %1 %2 %PARM3%
goto :EOF


:ROUTINE

Rem original code here

   echo do something 
   echo parm1=%1
   echo parm2=%2
   echo parm3=%3

goto :EOF
Output:

Code: Select all


T:\>parmtest2.cmd eins zwei {+
do something
parm1=eins
parm2=zwei
parm3=+
User avatar
Dalai
Power Member
Power Member
Posts: 9364
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Re: Mini-Skript-Anfrage

Post by *Dalai »

2NotNull
Die Positionsparameter des Skripts bleiben trotzdem fest. Mit call gerufene Sprungmarken haben ihre eigenen Parameter, aber auch diese sind innerhalb der Sprungmarke nicht änderbar. Nur weil ein Positionsparameter eines Skripts in einen Positionsparameter einer Sprungmarke konvertiert wird, heißt das nicht, dass Positionsparameter änderbar sind.

Nichtsdestotrotz ist das natürlich auch ein legitimer Ansatz, und in der Tat ein netter "Trick", diese Limitierung zu umgehen.

Grüße
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
NotNull
Senior Member
Senior Member
Posts: 266
Joined: 2019-11-25, 20:43 UTC
Location: NL

Re: Mini-Skript-Anfrage

Post by *NotNull »

Meine Zeit ist mir viel zu wertvoll um darüber endlos zu diskutieren, aber ich habe reagierte auf:
Dalai wrote: 2021-11-30, 21:08 UTC Positionsparameter von %0 bis %9 sind fest in ihrem Inhalt, d.h. nicht änderbar. Die einzige Änderung, die man in Bezug auf Positionsparameter machen kann, ist deren Position, d.h. Parameter %3 wird zu %2 und %2 wird zu %1 mittels des Befehls shift (siehe shift /? auf einer CMD). Positionsparameter %0 ist aber selbst dadurch nicht beeinflussbar, weil %0 immer das Skript selbst angibt.
Dauer-TC-ler
Junior Member
Junior Member
Posts: 53
Joined: 2015-03-14, 17:49 UTC

Re: Mini-Skript-Anfrage

Post by *Dauer-TC-ler »

na, na, wer wird denn gleich...
Post Reply