IT story

매개 변수에서 큰 따옴표 이스케이프

hot-time 2020. 9. 4. 08:06
반응형

매개 변수에서 큰 따옴표 이스케이프


유닉스에서는 실행할 수 myscript '"test"'있고 "test".

윈도우에서 cmd내가 얻을 'test'.

큰 따옴표를 매개 변수로 어떻게 전달할 수 있습니까? cmd프로그램을 테스트하기 위해 프로그램을 작성할 필요가 없도록 창 에서 수동으로이 작업을 수행하는 방법을 알고 싶습니다 .


증상을 빠르게 재현 할 수 없습니다.를 포함 하거나 심지어 포함 myscript '"test"'하는 배치 파일로 시도 하면 모든 따옴표가 표시됩니다.myscript.bat@echo.%1@echo.%~1'"test"'

아마도 다음 ^과 같이 이스케이프 문자를 시도 할 수 있습니다 . myscript '^"test^"'?


따옴표를 이스케이프하는 또 다른 방법은 (아마도 바람직하지는 않지만) 특정 장소에서 사용 된 것으로 나타났습니다 . 여러 개의 큰 따옴표사용하는 것 입니다. 다른 사람의 코드를 읽기 쉽게 만들기 위해 설명하겠습니다.

다음은 기본 규칙 집합입니다.

  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!"

따라서 큰 따옴표에는 세 가지 유형이 있습니다. 여는 따옴표, 닫는 따옴표, 일반 텍스트 역할을하는 따옴표입니다.
마지막으로 헷갈리는 라인의 분석은 다음과 같습니다.

"큰 따옴표 그룹 열기
T 내부 ""
나는 ""s 안에
m 내부 ""
    ""내부-공백이 분리되지 않음
s 내부 ""
내부 ""
y 내부 ""
s 내부 ""
, ""내부
    ""내부-공백이 분리되지 않음
"큰 따옴표로 묶인 그룹 닫기
"인용문이 바로 뒤에옵니다-일반 언 래핑 텍스트로 작동합니다."
""외부의 H-이전 인접 그룹에 결합됩니다.
나는 ""s 밖에-...
! 외부 ""-...
"큰 따옴표 그룹 열기
"큰 따옴표 그룹 닫기
"인용문이 바로 뒤에옵니다-일반 언 래핑 텍스트로 작동합니다."

따라서 텍스트는 4 개의 문자 그룹을 효과적으로 결합합니다 (하나는 아무것도 포함하지 않음) :
Tim says,  첫 번째는 공백을 벗어나기 위해  줄 바꿈 됨 두 번째는 줄 바꿈하지
"Hi!않음 (공백 없음)
세 번째는 큰 따옴표로 묶지 않음
"네 번째, 언 래핑 된 종가입니다.

보시다시피 큰 따옴표 그룹이 없으면 다음 큰 따옴표가 일반 텍스트로 작동하는 대신 큰 따옴표 그룹이 열리기 때문에 아무것도 래핑하지 않아도됩니다.

From this, it should be recognizable that therefore, inside and outside quotes, three double-quotes act as a plain-text unescaped double-quote:

"Tim said to him, """What's been happening lately?""""

will print Tim said to him, "What's been happening lately?" as expected. Therefore, three quotes can always be reliably used as an escape.
However, in understanding it, you may note that the four quotes at the end can be reduced to a mere two since it technically is adding another unnecessary empty double-quoted group.

Here are a few examples to close it off:

program a b                       REM sends (a) and (b)
program """a"""                   REM sends ("a")
program """a b"""                 REM sends ("a) and (b")
program """"Hello,""" Mike said." REM sends ("Hello," Mike said.)
program ""a""b""c""d""            REM sends (abcd) since the "" groups wrap nothing
program "hello to """quotes""     REM sends (hello to "quotes")
program """"hello world""         REM sends ("hello world")
program """hello" world""         REM sends ("hello world")
program """hello "world""         REM sends ("hello) and (world")
program "hello ""world"""         REM sends (hello "world")
program "hello """world""         REM sends (hello "world")

Final note: I did not read any of this from any tutorial - I came up with all of it by experimenting. Therefore, my explanation may not be true internally. Nonetheless all the examples above evaluate as given, thus validating (but not proving) my theory.

I tested this on Windows 7, 64bit using only *.exe calls with parameter passing (not *.bat, but I would suppose it works the same).


Try this:

myscript """test"""

"" escape to a single " in the parameter.


The 2nd document quoted by Peter Mortensen in his comment on the answer of Codesmith made things much clearer for me. That document was written by windowsinspired.com. The link repeated: A Better Way To Understand Quoting and Escaping of Windows Command Line Arguments.

Some further trial and error leads to the following guideline:

Escape every double quote " with a caret ^. If you want other characters with special meaning to the Windows command shell (e.g., <, >, |, &) to be interpreted as regular characters instead, then escape them with a caret, too.

If you want your program foo to receive the command line text "a\"b c" > d and redirect its output to file out.txt, then start your program as follows from the Windows command shell:

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

If foo interprets \" as a literal double quote and expects unescaped double quotes to delimit arguments that include whitespace, then foo interprets the command as specifying one argument a"b c, one argument >, and one argument d.

If instead foo interprets a doubled double quote "" as a literal double quote, then start your program as

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

The key insight from the quoted document is that, to the Windows command shell, an unescaped double quote triggers switching between two possible states.

Some further trial and error implies that in the initial state, redirection (to a file or pipe) is recognized and a caret ^ escapes a double quote and the caret is removed from the input. In the other state, redirection is not recognized and a caret does not escape a double quote and isn't removed. Let's refer to these states as 'outside' and 'inside', respectively.

If you want to redirect the output of your command, then the command shell must be in the outside state when it reaches the redirection, so there must be an even number of unescaped (by caret) double quotes preceding the redirection. foo "a\"b " > out.txt won't work -- the command shell passes the entire "a\"b " > out.txt to foo as its combined command line arguments, instead of passing only "a\"b " and redirecting the output to out.txt.

foo "a\^"b " > out.txt won't work, either, because the caret ^ is encountered in the inside state where it is an ordinary character and not an escape character, so "a\^"b " > out.txt gets passed to foo.

The only way that (hopefully) always works is to keep the command shell always in the outside state, because then redirection works.

If you don't need redirection (or other characters with special meaning to the command shell), then you can do without the carets. If foo interprets \" as a literal double quote, then you can call it as

foo "a\"b c"

Then foo receives "a\"b c" as its combined arguments text and can interpret it as a single argument equal to a"b c.

Now -- finally -- to the original question. myscript '"test"' called from the Windows command shell passes '"test"' to myscript. Apparently myscript interprets the single and double quotes as argument delimiters and removes them. You need to figure out what myscript accepts as a literal double quote and then specify that in your command, using ^ to escape any characters that have special meaning to the Windows command shell. Given that myscript is also available on Unix, perhaps \" does the trick. Try

myscript \^"test\^"

or, if you don't need redirection,

myscript \"test\"

참고URL : https://stackoverflow.com/questions/7760545/escape-double-quotes-in-parameter

반응형