유닉스에서는 실행할 수 myscript '"test"'
있고 "test"
.
윈도우에서 cmd
내가 얻을 'test'
.
큰 따옴표를 매개 변수로 어떻게 전달할 수 있습니까? cmd
프로그램을 테스트하기 위해 프로그램을 작성할 필요가 없도록 창 에서 수동으로이 작업을 수행하는 방법을 알고 싶습니다 .
유닉스에서는 실행할 수 myscript '"test"'
있고 "test"
.
윈도우에서 cmd
내가 얻을 'test'
.
큰 따옴표를 매개 변수로 어떻게 전달할 수 있습니까? cmd
프로그램을 테스트하기 위해 프로그램을 작성할 필요가 없도록 창 에서 수동으로이 작업을 수행하는 방법을 알고 싶습니다 .
답변:
증상을 빠르게 재현 할 수 없습니다.를 포함 하거나 심지어 포함 myscript '"test"'
하는 배치 파일로 시도 하면 모든 따옴표가 표시됩니다.myscript.bat
@echo.%1
@echo.%~1
'"test"'
아마도 다음 ^
과 같이 이스케이프 문자를 시도 할 수 있습니다 . myscript '^"test^"'
?
wscript
잘못 이라고 생각하지 않았을 것입니다 ! Windows
cmd
.
따옴표를 이스케이프하는 또 다른 방법은 (아마도 바람직하지는 않지만) 특정 장소에서 사용 된 것으로 나타났습니다 . 여러 개의 큰 따옴표 를 사용하는 것 입니다. 다른 사람의 코드를 읽기 쉽게 만들기 위해 설명하겠습니다.
다음은 기본 규칙 집합입니다.
program param1 param2 param 3
에 네 개의 매개 변수를 전달합니다 program.exe
: param1
, param2
, param
,와 3
.program one two "three and more"
로 세 개의 매개 변수를 전달합니다 program.exe
: one
, two
,와 three and more
.hello"to the entire"world
역할을합니다 : helloto the entireworld
."Tim says, ""Hi!"""
하나의 매개 변수로 작동합니다.Tim says, "Hi!"
따라서 큰 따옴표에는 세 가지 유형이 있습니다. 여는 따옴표, 닫는 따옴표, 일반 텍스트 역할을하는 따옴표입니다.
마지막으로 헷갈리는 라인의 분석은 다음과 같습니다.
"큰 따옴표 그룹 열기 T 내부 "" 나는 ""s 안에 m 내부 "" ""내부-공백이 분리되지 않음 s 내부 "" 내부 "" y 내부 "" s 내부 "" , ""내부 ""내부-공백이 분리되지 않음 "큰 따옴표로 묶인 그룹 닫기 "인용문이 바로 뒤에옵니다-일반 언 래핑 텍스트로 작동합니다." ""외부의 H-이전 인접 그룹에 결합됩니다. 나는 ""s 밖에-... ! 외부 ""-... "큰 따옴표 그룹 열기 "큰 따옴표 그룹 닫기 "인용문이 바로 뒤에옵니다-일반 언 래핑 텍스트로 작동합니다."
따라서 텍스트는 4 개의 문자 그룹을 효과적으로 결합합니다 (하나는 아무것도 포함하지 않음) :
Tim says,
첫 번째는 공백을 벗어나기 위해 줄 바꿈 됨 두 번째는 줄 바꿈하지
"Hi!
않음 (공백 없음)
세 번째는 큰 따옴표로 묶지 않음
"
네 번째, 언 래핑 된 종가입니다.
보시다시피 큰 따옴표 그룹이 없으면 다음 큰 따옴표가 일반 텍스트로 작동하는 대신 큰 따옴표 그룹이 열리기 때문에 아무것도 래핑하지 않아도됩니다.
따라서 따옴표 안팎에서 세 개의 큰 따옴표가 일반 텍스트 이스케이프 처리되지 않은 큰 따옴표 역할을한다는 것을 인식 할 수 있어야합니다.
"팀이 그에게 말했다." ""최근 무슨 일이 일어나고 있습니까? "" ""
Tim said to him, "What's been happening lately?"
예상대로 인쇄 됩니다. 따라서 세 개의 따옴표를 항상 안전하게 탈출구로 사용할 수 있습니다.
그러나 그것을 이해하면 기술적으로 불필요한 빈 큰 따옴표 그룹을 추가하기 때문에 끝에 4 개의 따옴표를 2 개로 줄일 수 있음을 알 수 있습니다.
다음은이를 종료하는 몇 가지 예입니다.
프로그램 ab REM은 (a) 및 (b)를 보냅니다. 프로그램 "" "a" ""REM이 전송 ( "a") 프로그램 "" "a b" ""REM은 ( "a) 및 (b")를 보냅니다. 프로그램 "" ""안녕하세요 "" "마이크가 말했다." REM은 ( "안녕하세요,"마이크가 말했다.) 프로그램 ""a ""b ""c ""d ""REM은 ""그룹이 아무것도 감싸지 않기 때문에 (abcd)를 보냅니다. 프로그램 "hello to" ""quotes ""REM이 전송 (hello to "quotes") 프로그램 "" ""hello world ""REM이 전송합니다 ( "hello world"). 프로그램 "" "hello"world ""REM이 전송합니다 ( "hello world"). 프로그램 "" "hello"world ""REM은 ( "hello) 및 (world")를 보냅니다. 프로그램 "hello" "world" ""REM이 전송합니다 (hello "world"). 프로그램 "hello" ""world ""REM이 전송합니다 (hello "world").
마지막 노트 : 나는 어떤 튜토리얼에서도 이것을 읽지 않았습니다. 실험을 통해 모든 것을 생각해 냈습니다. 따라서 내 설명은 내부적으로 사실이 아닐 수 있습니다. 그럼에도 불구하고 위의 모든 예는 주어진대로 평가되므로 내 이론을 검증 (그러나 증명하지는 않음)합니다.
매개 변수 전달 (* .bat 아님)과 함께 * .exe 호출 만 사용하여 Windows 7, 64 비트에서 이것을 테스트했지만 동일하게 작동한다고 가정합니다.
이 시도:
myscript """test"""
매개 변수에서 ""는 단일 "로 이스케이프합니다.
myscript """test test"""
와 그렇지 않은 작품은 (첫 번째 매개 변수는 다음과 같이 넘겨됩니다 않습니다 "test
. Acutally 세 가지 따옴표가 필요 myscript """"test test""
끝에 세 번째 따옴표는 생략 할 수있다, 그러나.
char **argv
C 런처에서 spawn
또는 같은 함수를 사용하여 다른 프로세스 로 전달해야 할 때 도움이되었습니다 exec
. 감사합니다. :-)
Codesmith의 답변에 대한 Peter Mortensen의 의견에서 인용 한 두 번째 문서는 저에게 상황을 훨씬 더 명확하게했습니다. 이 문서는 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
작동하지 않습니다-명령 셸 은 출력을 out.txt로 리디렉션하는 대신 결합 된 명령 줄 인수로 전체 "a\"b " > out.txt
를 foo 에 전달합니다 ."a\"b "
foo "a\^"b " > out.txt
캐럿 ^
이 이스케이프 문자가 아닌 일반 문자 인 내부 상태에서 발생 하기 때문에 작동 하지 않으므로 foo에"a\^"b " > out.txt
전달됩니다 .
(희망대로) 항상 작동하는 유일한 방법은 리디렉션이 작동하기 때문에 명령 셸을 항상 외부 상태로 유지하는 것입니다.
리디렉션 (또는 명령 셸에 특별한 의미가있는 다른 문자)이 필요하지 않으면 캐럿 없이도 할 수 있습니다. 경우 foo는 해석 \"
리터럴 큰 따옴표로는, 당신은 그것을 호출 할 수 있습니다
foo "a\"b c"
그런 다음 foo 는 "a\"b c"
결합 된 인수 텍스트로 수신 하고이를.와 같은 단일 인수로 해석 할 수 있습니다 a"b c
.
이제-마지막으로-원래 질문으로. myscript '"test"'
Windows 명령 셸에서 호출 '"test"'
하면 myscript로 전달 됩니다 . 분명히 myscript 는 작은 따옴표와 큰 따옴표를 인수 구분 기호로 해석하고 제거합니다. 당신은 무엇을 알아낼 필요 로 myscripf는 문자 그대로 따옴표로 받아 다음 사용하여 명령에 그 지정 ^
Windows 명령 쉘에 특별한 의미를 가지고있는 문자를 이스케이프 할 수 있습니다. myscript
유닉스에서도 사용할 수 있다는 점을 감안할 때 아마도 \"
트릭을 수행 할 것입니다. 시험
myscript \^"test\^"
또는 리디렉션이 필요하지 않은 경우
myscript \"test\"
myscript \"test\"