2016-09-27 34 views
5

ProblemJak przekazać parametr do pliku wsadowego zawierającego% bez "zerwania"?

W głównym pliku wsadowym wartości są wyciągane z pliku.txt (i SET jako wartości zmiennych, w tym plik wsadowy). Każda z tych wartości może zawierać znaki %.

Są one odczytywane z pliku .txt bez żadnych problemów. Jednak gdy zmienna o wartości zawierającej znak % jest przekazywana do drugiego pliku wsadowego, drugi plik wsadowy interpretuje dowolne znaki % jako rozszerzenie zmiennej. . (Uwaga: Nie nie kontrola drugi plik wsadowy)

Przykład

echo %PERCENTVARIABLE% 

wyjściowa: I%LOVE%PERCENT%CHARACTERS%

Po przekazaniu do drugiego pliku i echo'ed , będzie (prawdopodobnie) stanie się IPERCENT, ponieważ interpretuje %LOVE% i %CHARACTERS% jako zmienne nieustalone.


Badania

znalazłem składni znaleźć i zastąpić elementy ciągu znaków w pliku wsadowym, jak myślałem, że może potencjalnie zastąpić % postać z %% aby go uniknąć. Jednak nie mogę go uruchomić.

Składnia jest -

set string=This is my string to work with. 
set string=%string:work=play% 
echo %string% 

gdzie wyjście byłoby wtedy This is my string to play with..


Pytania

  1. Czy można uciec % znaków przy użyciu znaleźć i zastąpić składni w zmiennej? (Jeśli nie, czy jest inny sposób?)
  2. Czy jest to wskazane? (Czy użycie tych znaków wywołujących może spowodować problemy w drugim pliku wsadowym, który (jak wspomniano powyżej) nie miałby nad nim kontroli?)
  3. Czy istnieje inny sposób rozwiązania tego problemu, jeśli powyższe nie jest możliwe?
+3

Plik może być przetwarzany przez 'db_ham 'przy pomocy' jrepl.bat', jeśli zadanie nadaje się do manipulacji. jrepl używa jscript i może obsługiwać 'trucizny znaków'. – foxidrive

+0

@foxidrive Czy wiesz, jak wpłynęłoby to na użycie wartości zmiennych bezpośrednio w pierwszym skrypcie? Zmienne będą najprawdopodobniej używane w pierwszym skrypcie (mamy kontrolę), a także przekazywane na sekundę (nie pod naszą kontrolą). – Eilidh

+0

Przez "przekazanie do drugiego pliku", masz na myśli wywołanie go za pomocą 'call'? – aschipfl

Odpowiedz

1

może być ...?

input.txt

I%LOVE%PERCENT%CHARACTERS% 

BATCH1.bat

@echo off 
setlocal enableDelayedExpansion 
set/P var=<input.txt 
echo(In batch 1 var content: %var% 

set "var=!var:%%=%%%%!" 
call batch2.bat "%var%" 
endlocal 
exit/B 

batch2.bat

@echo off 
set "var=%~1" 
echo(In batch 2 var content: %var% 
exit/B 
+0

Działa to dla '%' ale kończy się niepowodzeniem dla '^', ponieważ będą one podwojone. Argumenty według wartości powinny być unikane przez 'CALL', jest wiele problemów – jeb

2

Nie ma prostych reguł, które mogą być stosowane w każdej sytuacji.

Istnieje kilka kwestii, które sprawiają, że praca z parametrów napisowych w trudnych:

  1. Poison znaków jak &, | itp muszą być notowane lub uciekły. Ucieczka jest trudna, ponieważ może być myląca, ile razy trzeba uciec. Zaleca się więc zwykle cytować ciąg znaków.
  2. Token ograniczników jak <space>, <tab>, =, ; i , nie mogą być uwzględnione w wartości parametru, chyba że jest cytowany.
  3. Wywołanie skryptu podwoi wszystkie cytowane znaki % i istnieje w żaden sposób, aby temu zapobiec:. Wykonywanie skryptu bez wywołania nie spowoduje podwojenia liczby znaków %. Jeśli jednak skrypt wywoła inny skrypt i oczekuje, że kontrola zostanie zwrócona, należy użyć polecenia CALL.

Mamy więc catch-22: Z jednej strony chcemy przytoczyć parametry chroniące przed truciznami znaków i spacji (ogranicznikami tokenów). Ale żeby chronić procenty, nie chcemy zacytować.

Jedyną niezawodną metodą niezawodnego przekazywania literałów łańcuchów bez obaw o uszkodzenie wartości jest przekazywanie ich przez odniesienie za pomocą zmiennych środowiskowych.

  1. Wartość do przekazania powinna być przechowywana w wartości środowiska. Cytaty i/lub ucieczki i/lub podwojenie procentu są używane do uzyskania niezbędnych znaków w wartości, ale jest to bardzo łatwe w zarządzaniu.
  2. Nazwa zmiennej jest przekazywana jako parametr.
  3. Skrypt uzyskuje dostęp do wartości poprzez opóźnione rozwinięcie. Na przykład, jeśli pierwszy parametr jest nazwą zmiennej zawierającej wartość, wówczas jest dostępny jako !%1!. Opóźnione rozszerzenie musi zostać włączone przed użyciem tej składni - wystarczy wydać setlocal enableDelayedExpansion.

Piękno opóźnionej ekspansji nigdy nie musisz martwić się o korupcję zatrutych znaków, spacji lub procentów, gdy zmienna zostanie rozwinięta.

Oto przykład, który pokazuje, w jaki sposób następujący ciąg dosłowne mogą być przekazywane do podprogramu
"<%|,;^> This & that!" & the other thing! <%|,;^>

@echo off 
setlocal enableDelayedExpansion 
set "parm1="^<%%^|,;^^^^^> This ^& that^^!" & the other thing^! <%%|,;^^^>" 
echo The value before CALL is !parm1! 
call :test parm1 
exit /b 

:test 
echo The value after CALL is !%1! 

- WYJŚCIE -

The value before CALL is "<%|,;^> This & that!" & the other thing! <%|,;^> 
The value after CALL is "<%|,;^> This & that!" & the other thing! <%|,;^> 

Ale stwierdzenie, że nie masz kontrola nad drugim zwanym skryptem. Tak więc powyższe eleganckie rozwiązanie nie będzie działać dla Ciebie.

Jeśli miałbyś pokazać kod drugiego skryptu i pokazać dokładnie, jaką wartość próbujesz przekazać, wtedy może podać rozwiązanie, które działałoby w tej odosobnionej sytuacji. Ale są pewne wartości, które po prostu nie mogą zostać przekazane, jeśli opóźnione rozwinięcie nie jest używane z nazwami zmiennych. (W rzeczywistości inną opcją jest umieszczenie wartości w pliku i odczytanie wartości z pliku, ale to również wymaga zmiany w drugim skrypcie)