Що робить остання частина заданих парам =% *: “=” "?


3

Я працюю з пакетним сценарієм, для якого потрібні права адміністратора, і я запозичив з мережі "чистий код get-admin". Я намагаюся розібратися, що робить остання частина конкретного рядка:

set params = %*:"=""

Я знаю, що перша частина створює змінну, а потім отримує весь набір параметрів, переданих сценарію;

set params = %*

Але що на землі це робить?

:"=""

Відповіді:


5

Якщо припустити, що ви правильно скопіювали код - він взагалі нічого не робить. :"=""Буквальний просто додаються до розширеної рядку аргументу.

Якби у вас був %*:"=""%(зверніть увагу на додаткові відсотки), він би розширив змінну середовища, названу *, замінивши дві лапки для кожної.

Функція пошуку / заміни розширення доступна лише для змінних розширень, а не для розширення аргументів.

Я б хотів поставити під сумнів, що це помилка, яку ввів хтось, хто має дуже мало досвіду роботи з пакетною мовою.

Майже напевно є ще одна помилка - Усі пробіли у призначенні значні. Таким чином, це створює змінну з назвою "params "(без лапок, зверніть увагу на пробіл). Також значення матиме провідний простір. Я впевнений, що ні місця не хочеться.

Оновлена, більш повна відповідь

Тепер, коли ми знаємо джерело коду , можна дати більш повне уявлення про те, що відбувається. Потрібно більше контексту коду.

Оригінальними відповідними рядками є:

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

Оригінальний пакетний сценарій вимагав, щоб він був запущений з підвищеними правами адміністратора. Сценарій міг визначити, чи доступні адміністративні приватні файли, а якщо ні, то він створив тимчасовий сценарій VBS, який під час запуску створить новий cmd.exe сеанс з адміністративними приватними файлами та повторно повторить оригінальний пакетний сценарій з тими ж оригінальними аргументами . Команда для повторного виконання сценарію вбудована у рядок VBS, і рядок може містити аргументовані аргументи. VBS вимагає, щоб цивілізовані цитати в рядку були уникнуті шляхом їх подвоєння.

Оригінальна відповідь не зберегла аргументів і не мала paramsзмінної. Через рік ОП намагалася поширити відповідь на підтримку збереження позитивних аргументів. На жаль, модифікований код ніколи не був належним чином перевірений, і "розширення" серйозно помилилось. Якщо ви подивитесь на безліч коментарів до цієї відповіді, ви можете побачити багато звітів про те, що збереження аргументів все ще не працювало.

Спочатку код визначає змінну з назвою "params" (з пробілом), а потім намагається використовувати невизначену змінну під назвою "params" (без пробілу). Це, очевидно, не може працювати. Але просто видалення пробілів із визначення нічого не вирішує.

set params=%*:"=""

ОП, мабуть, подумав, що синтаксис розшириться на початковий рядок аргументу, причому всі лапки подвоїться. Але пошук / заміна працює лише під час розширення змінних, а не аргументів.

Припустимо, оригінальний пакетний сценарій є c:\test\test.bat, і він називається використанням

test arg1 "arg 2" "arg 3"

Рядок "виправлений" set params=%*:"=""просто отримує копію аргументів %*, а потім додає :"=""рядок. Отже, коли повна, змінна визначається наступним чином:

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

Але ОП насправді хотів:

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

Наступний рядок, який використовується для повторного виконання сценарію з правами адміністратора, не вдасться. Він розшириться до:

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

Ось код, як він повинен був бути написаний:
EDIT 2018-9-23: додано простір до призначення парам, щоб переконатися, що він завжди визначений, навіть якщо аргументів немає

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

Перший рядок просто визначає параметри як

params= arg1 "arg 2" "arg 3"

А наступний рядок використовує :"=""синтаксис, щоб подвоїти всі лапки під час розширення paramsзмінної:

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

Оригінальні аргументи збережені, і всі цитати були належним чином подвоєні.

Я відредагував оригінальну відповідь, щоб включити виправлення помилок.


Ще кілька досліджень цього показують, що ця відповідь невірна. % * - це посилання на всі параметри, передані через файл .cmd. Отже: myfile.cmd 1 2 3 4 5дасть "1 2 3 4 5" всередині% *, подібно до% 1, який дає лише 1.
LPChip

@LPChip - А ​​що в моїй відповіді невірно? Коли я посилався на "розширений рядок аргументів", це саме те, що я мав на увазі. У вашому прикладі розширення %*(рядок аргументу) справді є 1 2 3 4 5, а потім :"=""додається. Можливо, я міг би навести приклад, щоб зробити все більш зрозумілим, але я не бачу жодних неправильних тверджень у своїй відповіді.
dbenham

У моєму первинному виправленні була помилка, якщо не було передано жодних аргументів. Я додав пробіл у призначенні парам, щоб виправити помилку.
dbenham
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.