Як я можу уникнути оклику! в скриптах cmd?


77

Коли я setlocal ENABLEDELAYEDEXPANSIONвстановив скрипт cmd, чи є спосіб, яким я можу уникнути! що я хочу використовувати як параметр для команди?

@echo off
setlocal ENABLEDELAYEDEXPANSION
echo I want to go out with a bang!
echo I still want to go out with a bang^!

Відповіді:


11

Нижче наведено приклад того, як ми можемо використовувати змінну знака оклику у станах DISABLEDELAYEDEXPANSION та ENABLEDELAYEDEXPANSION .

@echo off
setlocal DISABLEDELAYEDEXPANSION
set DB_password=encrypt!Pws
echo %DB_password%
SETLOCAL ENABLEDELAYEDEXPANSION
echo !DB_password!

Краща відповідь! Це вирішує використання в скриптах, де потрібен DELAYEDEXPANSION.
JasonXA

Це аберративно. Ніде в цих вимогах пам'ять не викликає занепокоєння, і все ж я використовую її багато, не маючи негативного впливу. Якщо ви не можете насправді внести свій внесок, тримайте свої дурниці в собі.
JasonXA

Я насправді написав свій код, як ваш, тоді подумав: "це не може працювати, тому що! Буде втрачено з увімкненим відкладеним розширенням", шукав рішення в усьому Інтернеті, приземлився тут, прочитав останню відповідь і з'ясував, що мій код міг би мати працював весь час, я просто не зрозумів, що його замінюють лише один раз ... Велике дякую ^! ^! ; D
timlg07

88

Це те, що я знайшов (^^)

@echo off
setlocal ENABLEDELAYEDEXPANSION
echo I want to go out with a bang^^!

2
До речі, якби вам довелося замінити знак оклику всередині змінної, як би ви це зробили?
crosenblum

2
@crosenblum Я б рекомендував задати це як власне запитання. Тоді це буде доступним для всіх членів SO та, швидше за все, відповість.
FrVaBe

1
Це (ані інші рішення) не спрацює, якщо знак оклику знаходиться всередині змінної, яку ви встановили / використовуєте або передаєте мітці виклику, і в цьому випадку, я думаю, вам не пощастить.
Абель

65

Додаткове зауваження до відповіді на FrVaBe .

Зазвичай це ^^!працює, але в лапки вам потрібно лише ^!замість цього.

echo I want to go out with a bang^^!
echo He said "Bang^!"

Це результат механізму втечі пакетного аналізатора.

Спочатку синтаксичний аналізатор аналізує рядок, а каретка уникає наступного символу, в цьому випадку це має ефект для &|<>()"<linefeed>, але лише поза лапками, оскільки всередині лапок усі символи є "нормальними", а сама каретка не має ефекту.

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

setlocal DisableDelayedExpansion
echo DisableDelayedExpansion
echo one caret^^
echo one caret^^  bang! "boom^!"

echo(
setlocal EnableDelayedExpansion
echo EnableDelayedExpansion
echo one caret^^
echo none caret^^  bang^^! "boom^!"

---- ВИХІД ------

DisableDelayedExpansion
one caret^
one caret^  bang! "boom^!"

EnableDelayedExpansion
one caret^
none caret  bang! "boom!"


РЕДАГУВАТИ

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

@echo off
setlocal DisableDelayedExpansion
echo DisableDelayedExpansion
echo caret^^       "caret^"
echo caret^^ bang! "caret^ bang!"

echo(
setlocal EnableDelayedExpansion
echo EnableDelayedExpansion
echo caret^^       "caret^"
echo caret^^^^ bang^^! "caret^^ bang^!"

- ВИХІД -

DisableDelayedExpansion
caret^       "caret^"
caret^ bang! "caret^ bang!"

EnableDelayedExpansion
caret^       "caret^"
caret^ bang! "caret^ bang!"

6

Дякую. Щоб додати до цієї цінної точки, якщо скрипт містить змінну, значення якої містить "!", Наступний підхід зробить це значення таким, як є:

@echo вимкнено
SETLOCAL EnableDelayedExpansion
set / P omg = Введіть значення, що містить знак оклику:
ехо Традиційне:% omg%
echo Альтернатива:! omg!
пауза
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.