Уникнути подвійних лапок у параметрі


109

В Unix я міг бігати, myscript '"test"'і я дістався "test".

У Windows cmdя потрапляю 'test'.

Як я можу передавати подвійні лапки як параметр? Я хотів би знати, як це зробити вручну з cmdвікна, тому мені не потрібно писати програму, щоб перевірити свою програму.


2
Минуло роки, як я торкнувся машини Windows, але чи не працює стандартний символ втечі (зворотний косий рядок)? наприкладmyscript \"test\"
Газлер

Ні. Я отримую \ тест \. Я підозрюю, що це тому, що Windows використовує \ замість / тому зворотну косу рису не можна використовувати як ескапер. Але я насправді не знаю.
Брайан Філд

Ідентифікуйте, яку версію Windows ви використовуєте, але \ "відмінно працює в Windows 7 (Ultimate). Є ще один спосіб зробити це, хоча, маючи декілька лапок (тобто" "" стає "чи щось таке", але я не можу з'ясувати, коли і як це працює.
Codesmith

Відповіді:


22

Я не можу швидко відтворити симптоми: якщо я спробую myscript '"test"'з пакетним файлом, myscript.batщо містить просто @echo.%1або навіть @echo.%~1, я отримую всі лапки:'"test"'

Можливо, ви можете спробувати втечу персонажа ^так myscript '^"test^"':?


3
Тоді, можливо, відповіді на це питання можуть допомогти вам далі?
mousio

2
Га! Я ніколи б не здогадувався, що це wscriptвинна! Залиште це у Windows :)
Брайан Філд

4
На насправді ^ не працював для мене, але \ зробив, за цей відповідь: stackoverflow.com/questions/2403647 / ...
kalenjordan

26
Windows: ОС, де глобалізація, розширення оболонки та скасування параметрів виконується виконуваним виконуваним файлом замість оболонки. Ніколи не знаєш, яка конвенція, якщо така є, викликала виконувані відзнаки.
бінкі

7
Цінний внесок: blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04 / ... . Карета - це справді втікаючий персонаж вибору cmd.
Пітер - Відновіть Моніку

198

Ще один спосіб уникнути цитат (хоча, мабуть, не кращий), який я знайшов використовуваним у певних місцях, - це використовувати кілька подвійних лапок . Для того, щоб зробити код інших людей розбірливим, я поясню.

Ось набір основних правил:

  1. Коли НЕ загорнуті в подвійних лапках груп, пробілу окремих параметрів:
    program param1 param2 param 3будуть проходити чотири параметри program.exe:
         param1, param2, param, і 3.
  2. Група подвійних лапок ігнорують пробілу в якості значення роздільників при передачі параметрів програми:
    program one two "three and more"буде проходити три параметра в program.exe:
         one, two, і three and more.
  3. Тепер пояснимо деяку плутанину:
  4. Двічі цитовані групи , які з'являються безпосередньо поруч з текстом , НЕ загорнутий в подвійних лапках об'єднуються в один параметр:
    hello"to the entire"worldдіє як один параметр: helloto the entireworld.
  5. Примітка: Попереднє правило НЕ означає, що дві групи з подвійним цитуванням можуть з'являтися безпосередньо поруч одна з одною.
  6. Будь-яка подвійна цитата безпосередньо після завершальної цитати трактується як (або як частина) простого розгорнутого тексту, який примикає до групи з подвійним цитуванням, але лише одна подвійна цитата:
    "Tim says, ""Hi!"""буде діяти як один параметр:Tim says, "Hi!"

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

"відкрити групу з подвійною цитатами
Т всередині "" s
i всередині "" s
м всередині "" s
    всередині "" s - простір не відокремлюється
s всередині "" s
всередині "" s
y всередині "" s
s всередині "" s
, всередині "" s
    всередині "" s - простір не відокремлюється
"близька група з подвійним котируванням
"цитата безпосередньо слідує ближче - діє як звичайний розгорнутий текст:"
H назовні "" - приєднується до попередньої сусідньої групи
я за межами "" s - ...
! за межами "" s - ...
"відкрити групу з подвійною цитатами
"закрити групу з подвійним цитуванням
"цитата безпосередньо слідує ближче - діє як звичайний розгорнутий текст:"

Таким чином, текст ефективно приєднується до чотирьох груп символів (одна з них нічого, однак):
Tim says,  перша, обгорнута для втечі з пробілів
"Hi!, друга, не загорнута (пробілів немає)
 - третя, група з подвійним цитуванням, яка нічого не містить
"це четверта, розгорнута близька цитата.

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

З цього слід зрозуміти, що тому внутрішні та зовнішні лапки три подвійні лапки виступають як двозначна двозначна цивільна мова:

"Тим сказав йому", "Що відбувається останнім часом?"

буде надруковано, Tim said to him, "What's been happening lately?"як очікувалося. Тому три лапки завжди можна надійно використовувати як втечу.
Однак, розуміючи це, ви можете зауважити, що чотири лапки в кінці можна зменшити до лише двох, оскільки технічно це додає ще одну непотрібну порожню групу з подвійним котируванням.

Ось кілька прикладів, щоб закрити це:

програма ab REM посилає (a) і (b)
програма "" "a" "" REM відправляє ("a")
програма "" "a b" "" REM посилає ("a) і (b")
програма "" "" Привіт "," Майк сказав. " REM надсилає ("Привіт", сказав Майк.)
program "" a "" b "" c "" d "" REM посилає (abcd), оскільки "" групи нічого не переносять
програма "привіт до" "" котирування "" REM надсилає (привіт "котирування")
програма "" "" привіт світ "" REM надсилає ("привіт світ")
програма "" "привіт" світ "" REM надсилає ("привіт світ")
програма "" "привіт" світ "" REM посилає ("привіт) і (світ")
програма "привіт" "світ" "" REM посилає (привіт "світ")
програма "привіт" "" світ "" REM посилає (привіт "світ")

Заключна примітка: я нічого з цього не читав з жодного підручника - я все це придумав, експериментуючи. Тому моє пояснення може бути неправдивим внутрішньо. Тим не менш, усі приклади вище оцінюються як наведені, таким чином підтверджуючи (але не доводячи) мою теорію.

Я перевірив це на Windows 7, 64bit, використовуючи лише * .exe дзвінки з проходженням параметра (не * .bat, але я б припустив, що він працює так само).


11
+1, але зауважте, що така поведінка залежить від програми. У Windows кожна програма аналізує власні параметри командного рядка. Я вважаю, що поведінка, яку ви описуєте, - це стандартна бібліотека C Microsoft, яку, на мою думку, також дублює більшість інших компіляторів Windows C.
Гаррі Джонстон

3
Кілька помилок у вашому останньому досвіді. програма "" "ab" "" -> ("ab"), програма "привіт до" "" котирування "" -> (привіт до "котирування), програма" "" "привіт світ" "-> (" Привіт) " (світ), програма "" "привіт" світ "" -> ("привіт) (світ), програма" "" привіт "світ" "-> (" привіт світ "), програма" привіт "" "світ" "- > (привіт "світ"
Томсон

46
... Все, що я можу сказати, це те, що пакетні файли Windows мають проблеми. Це уникнення цитат , заради Христа; це не повинно бути якоюсь ракетною наукою.
Джеймс Ко

4
@JamesKo Я не міг більше погодитися. Таємна абсурдність та непослідовність командного рядка Windows ніколи не злість мене. Хто сконструював цей мотлох? О, години витрачені на роки! Unix такий простий і має стільки сенсу в порівнянні.
Карлос А. Ібарра,


24

Спробуйте це:

myscript """test"""

"" біг до одиниці "в параметрі.


1
Це не зовсім правильно. Спробуйте, myscript """test test"""і це не спрацює (перший параметр передається як "test. Акутально, вам потрібно три лапки: myscript """"test test""Однак, третю цитату в кінці можна пропустити.
Ignitor

що робити, якщо мені потрібно видалити всі лапки і розмістити значення параметра в рядку, що використовується у фільтрі вибору запитів? Може хтось допоможе?
SFDC_Learner

2
Можливо, я не звертаюся до цього питання, але це допомогло мені, коли мені потрібно було перейти char **argvзі свого запуску C на інший процес, використовуючи такі функції, як spawnабо exec. Дякую. :-)
virgo47

2

Другий документ, який цитував Пітер Мортенсен у своєму коментарі до відповіді Кодесміта, зробив для мене речі набагато зрозумілішими. Цей документ написав windowsinspired.com. Посилання повторилося: Кращий спосіб зрозуміти цитування та уникнення аргументів командного рядка Windows .

Деякі подальші спроби та помилки призводять до наступних рекомендацій:

Уникайте кожної подвійної цитати "за допомогою карети ^. Якщо ви хочете , щоб інші символи зі спеціальним значенням для командної оболонки Windows , (наприклад, <, >, |, &) повинні інтерпретуватися як звичайні символи замість цього, то позбутися від них з кареткою, теж.

Якщо ви хочете, щоб ваша програма foo отримувала текст командного рядка "a\"b c" > dі перенаправляла його вихід на файл out.txt , тоді запустіть програму, як випливає з командної оболонки Windows:

foo ^"a\^"b c^" ^> d > out.txt

Якщо foo інтерпретується \"як буквальна подвійна цитата і очікує, що нескопічні подвійні лапки розмежуватимуть аргументи, що містять пробіл, тоді foo трактує команду як вказівку одного аргументу a"b c, одного аргументу >та одного аргументу d.

Якщо замість foo трактується подвійна подвійна цитата ""як буквальна подвійна цитата, тоді запустіть програму як

foo ^"a^"^"b c^" ^> d > out.txt

Ключове розуміння цитованого документа полягає в тому, що для оболонки команди Windows незмінна подвійна цитата викликає перехід між двома можливими станами.

Деякі подальші спроби та помилки означають, що в початковому стані перенаправлення (до файлу чи труби) розпізнається, а карета ^уникає подвійної лапки, а карету вилучають із вводу. В іншому стані перенаправлення не розпізнається, і карета не уникає подвійної лапки і не видаляється. Давайте будемо називати ці стани відповідно «зовні» та «всередині».

Якщо ви хочете перенаправити висновок вашої команди, тоді оболонка команди повинна знаходитися у зовнішньому стані, коли вона досягне перенаправлення, тому перед переадресацією має бути парне число подвійних лапок (за допомогою карети). foo "a\"b " > out.txtне працюватиме - командна оболонка передає цільну "a\"b " > out.txtдля взувши як його комбіновані аргументи командного рядка, замість передачі тільки "a\"b "і перенаправляти висновок в out.txt .

foo "a\^"b " > out.txtтакож не вийде, тому що карета ^зустрічається у внутрішньому стані, де він є звичайним персонажем, а не символом втечі, тому "a\^"b " > out.txtпередається в foo .

Єдиний спосіб, який (сподіваємось) завжди працює, - це тримати командну оболонку завжди у зовнішньому стані, адже тоді перенаправлення працює.

Якщо вам не потрібно перенаправлення (або інші символи зі спеціальним значенням для оболонки команди), ви можете обійтися без уваги. Якщо foo трактується \"як буквальна подвійна цитата, то ви можете назвати це як

foo "a\"b c"

Тоді foo отримує "a\"b c"як об'єднаний текст аргументів і може інтерпретувати його як єдиний аргумент, рівний a"b c.

Тепер - нарешті - до початкового питання. myscript '"test"'виклик із командної оболонки Windows переходить '"test"'до myscript . Мабуть, сценарій інтерпретує одиночні та подвійні лапки як розмежувачі аргументів та видаляє їх. Потрібно розібратися, який сценарій приймається як буквальна подвійна цитата, а потім вказати це у вашій команді, використовуючи ^для втечі будь-які символи, що мають особливе значення для командної оболонки Windows. Зважаючи на те, що myscriptтакож доступно на Unix, можливо, \"це і є фокус. Спробуйте

myscript \^"test\^"

або, якщо вам не потрібно перенаправлення,

myscript \"test\"

СПАСИБІ! Я бив головою об стіну, намагаючись запустити vbscript з текстом підказки cmd, який перегукувався з текстом підказки cmd - я це успадкував - і не міг знайти спосіб уникнути цитат.
PopeDarren

0

Я називаю powerhell від cmd, і передача цитат, і жодна ескадра тут не працює. Грібний акцент працював на те, щоб уникнути подвійних цитат на цій програмі Win 10.

>powershell.exe "echo la`"" >> test
>type test
la"

Нижче наведено результати, які я отримав для інших персонажів, щоб уникнути подвійної цитати:

la\
la^
la
la~

Використання іншої цитати для виходу з цитати не призвело до жодних лапок. Як бачимо, самі персонажі набралися, але не уникнули подвійних лапок.

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