Co robi ostatnia część zestawu params =% *: „=” ”?

3

Pracuję ze skryptem wsadowym, który wymaga uprawnień administratora i pożyczyłem kod „get-admin-rights” z sieci. Próbuję dowiedzieć się, co robi ostatnia część konkretnej linii:

set params = %*:"=""

Wiem, że pierwsza część tworzy zmienną, a następnie pobiera cały zestaw parametrów przekazanych do skryptu;

set params = %*

Ale co u licha jest to robić?

:"=""
David Mancini
źródło

Odpowiedzi:

5

Zakładając, że kod został skopiowany poprawnie - nie robi to nic specjalnego. The :"="" literał jest po prostu dołączany do rozszerzonego ciągu argumentów.

Gdybyś miał %*:"=""% (zwróć uwagę na dodatkowy procent), a następnie rozszerzyłby zmienną środowiskową o nazwie *, zastępując dwa cytaty dla każdego.

Funkcja rozszerzenia Znajdź / Zamień jest dostępna tylko dla rozszerzenia zmiennych, a nie dla rozszerzenia argumentów.

Chciałbym się założyć, że jest to błąd wprowadzony przez kogoś, kto ma bardzo małe doświadczenie z językiem wsadowym.

Prawie na pewno jest jeszcze jeden błąd - wszystkie spacje w przydziale są znaczące. Więc tworzy zmienną o nazwie "params " (bez cudzysłowu zanotuj spację). Ponadto wartość będzie miała wiodącą przestrzeń. Jestem prawie pewien, że nie jest potrzebna przestrzeń.

Zaktualizowana, pełniejsza odpowiedź

Teraz, gdy wiemy źródło kodu , możliwe jest uzyskanie pełniejszego obrazu tego, co się dzieje. Potrzebny jest więcej kontekstu kodu.

Oryginalne odpowiednie wiersze to:

set params = %*:"=""
echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"

Oryginalny skrypt wsadowy wymagał uruchomienia go z podwyższonymi uprawnieniami administratora. Skrypt był w stanie określić, czy dostępne są uprawnienia administratora, a jeśli nie, to utworzył tymczasowy skrypt VBS, który po uruchomieniu utworzył nową sesję cmd.exe z uprawnieniami administratora i ponownie uruchomił oryginalny skrypt wsadowy z tymi samymi oryginalnymi argumentami . Polecenie ponownego uruchomienia skryptu jest osadzone w łańcuchu VBS, a łańcuch może zawierać cytowane argumenty. VBS wymaga, aby literały cytatów w ciągu znaków były unikane przez ich podwojenie.

Oryginalna odpowiedź nie zachowała argumentów i nie miała żadnych params zmienna. Rok później PO próbował rozszerzyć odpowiedź, aby wesprzeć zachowanie argumentów wywołujących. Niestety zmodyfikowany kod nigdy nie został poprawnie przetestowany, a „ulepszenie” zostało poważnie zablokowane. Jeśli spojrzysz na wiele komentarzy do tej odpowiedzi, zobaczysz wiele raportów, że zachowanie argumentów nadal nie działa.

Po pierwsze, kod definiuje zmienną o nazwie „params” (z końcową spacją), a następnie próbuje użyć niezdefiniowanej zmiennej o nazwie „params” (bez spacji końcowych). To oczywiście nie działa. Ale samo usunięcie spacji z definicji nic nie rozwiązuje.

set params=%*:"=""

OP musiał pomyśleć, że składnia rozszerzy się do oryginalnego ciągu argumentów, a wszystkie cytaty podwoją się. Ale find / replace działa tylko podczas rozwijania zmiennych, a nie argumentów.

Załóżmy, że oryginalny skrypt wsadowy to c:\test\test.bati nazywa się to używaniem

test arg1 "arg 2" "arg 3"

„Poprawiona” linia set params=%*:"="" po prostu dostaje kopię argumentów za pomocą %*, a następnie dołącza :"="" strunowy. Po zakończeniu zmienna jest definiowana następująco:

params=arg1 "arg 2" "arg 3":"=""

Ale OP rzeczywiście chciał:

params=arg1 ""arg 2"" ""arg 3""

Następna linia używana do ponownego wykonania skryptu z uprawnieniami administratora nie powiedzie się. Rozszerzyłby się na:

echo UAC.ShellExecute "cmd.exe", "/c ""c:\test\test.bat"" arg1 "arg 2" "arg 3":"=""", "", "runas", 1 >> "someTempPath\getadmin.vbs"

Oto kod, który powinien być napisany:
EDYCJA 2018-9-23: dodano spację do przypisania params, aby upewnić się, że jest zawsze zdefiniowane, nawet jeśli nie ma żadnych argumentów

set params= %*
echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params:"=""%", "", "runas", 1 >> "%temp%\getadmin.vbs"

Pierwsza linia po prostu definiuje parametry jako

params= arg1 "arg 2" "arg 3"

A kolejna linia używa :"="" składnia podwajająca wszystkie cudzysłowy podczas rozwijania params zmienna:

echo UAC.ShellExecute "cmd.exe", "/c ""c:\test\test.bat""  arg1 ""arg 2"" ""arg 3""", "", "runas", 1 >> "someTempPath\getadmin.vbs"

Oryginalne argumenty są zachowywane, a wszystkie cytaty zostały poprawnie podwojone.

mam edytowałem oryginalną odpowiedź włączyć poprawki błędów.

dbenham
źródło
Kolejne badania na ten temat pokazują, że ta odpowiedź jest niepoprawna. % * to odwołanie do wszystkich parametrów przekazywanych przez plik .cmd. Więc: myfile.cmd 1 2 3 4 5 da „1 2 3 4 5” wewnątrz% *, podobnie jak% 1, dając tylko 1.
LPChip
@LPChip - A co jest nie tak w mojej odpowiedzi? Kiedy mówiłem o „rozszerzonym łańcuchu argumentów”, to właśnie miałem na myśli. W twoim przykładzie rozszerzenie %* (ciąg argumentu) jest rzeczywiście 1 2 3 4 5, i wtedy :"="" jest dołączony. Być może mógłbym podać przykład, aby wyjaśnić sprawę, ale nie dostrzegam w mojej odpowiedzi żadnych błędnych stwierdzeń.
dbenham
W mojej oryginalnej poprawce wystąpił błąd, jeśli nie przekazano żadnych argumentów. Dodałem spację do zadania params, aby naprawić błąd.
dbenham