2016-06-24 3 views
3

다른 곳에서 호출하려는 명령의 일부 (Git 명령)에 PowerShell 변수를 할당하려고합니다. 내가 기대하고있어내 PowerShell 따옴표가 올바르게 이스케이프 처리되지 않는 이유

$gitExe = "`"$env:programfiles\Git\bin\git.exe`" -C `"$solutionFolder`"" 

이 같은 값을 생성 : :이 라인이 스크립트가 (비주얼 스튜디오 2015 안에 NuGet 패키지 설치의 일부로서)를 실행하는 경우, 대신

"C:\Program Files\Git\bin\git.exe" -C "C:\MySolution" 

Invoke-Expression : At line:1 char:3 
+ ""C:\Program Files (x86)"\Git\bin\git.exe -C "C:\MySolution ... 
+ ~~~~~~~~~~ 
Unexpected token 'C:\Program' in expression or statement. 

내가 PowerShell을 새로운 해요, 제가 다른 답변에서 제안을 시도하지만, 나는 그것이 (모든 다른 종류의 실패로) 작업을 가져올 수 없습니다 :이 오류가 발생합니다. 큰 따옴표 안에

$gitExe = Join-Path $env:programfiles '\Git\bin\git.exe' 
& $gitExe -c $solutionFolder 
+0

당신은'''를 벗어나지 않으려면'''와'''를 사용하려고 시도 했습니까? – sodawillow

+0

@sodawillow 나는 그 반대를 시도했지만 그것이 효과가있는 것처럼 보였다. 감사합니다. – Dov

답변

3

AFAICS 도망 치는 데는 아무 문제가 없지만 오히려 Invoke-Expression의 작동 방식을 오해하고 있습니다. cmdlet은 주어진 문자열을 명령 줄로 실행하는 방법을 제공합니다. 그러나 call operator (&)을 사용하지 않으면 PowerShell에서 명령 줄의 명령으로 노출 된 문자열 (해당 경우 "C:\Program Files\Git\bin\git.exe")을 명령으로 사용할 수 없습니다. 대신은 예기치 않은 토큰 문자열을 에코을 시도하지만 실패합니다

데모 :

PS C:\>"$env:windir\system32\ping.exe" 
C:\Windows\system32\ping.exe 
PS C:\>"$env:windir\system32\ping.exe" -n 1 127.0.0.1 
At line:1 char:33 
+ "$env:windir\System32\PING.EXE" -n 1 127.0.0.1 
+         ~~ 
Unexpected token '-n' in expression or statement. 
At line:1 char:36 
+ "$env:windir\System32\PING.EXE" -n 1 127.0.0.1 
+         ~ 
Unexpected token '1' in expression or statement. 
At line:1 char:38 
+ "$env:windir\System32\PING.EXE" -n 1 127.0.0.1 
+          ~~~~~~~~~ 
Unexpected token '127.0.0.1' in expression or statement. 
    + CategoryInfo   : ParserError: (:) [], ParentContainsErrorRecordException 
    + FullyQualifiedErrorId : UnexpectedToken 

PS C:\>& "$env:windir\system32\ping.exe" -n 1 127.0.0.1 

Pinging 127.0.0.1 with 32 bytes of data: 
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 

Ping statistics for 127.0.0.1: 
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss), 
Approximate round trip times in milli-seconds: 
    Minimum = 0ms, Maximum = 0ms, Average = 0ms
PS C:\>$cmd = "'$env:windir\system32\ping.exe' -n 1 127.0.0.1" 
PS C:\>$cmd 
'C:\Windows\system32\ping.exe' -n 1 127.0.0.1 
PS C:\>Invoke-Expression $cmd 
Invoke-Expression : At line:1 char:32 
+ 'C:\Windows\system32\ping.exe' -n 1 127.0.0.1 
+        ~~ 
Unexpected token '-n' in expression or statement. 
At line:1 char:35 
+ 'C:\Windows\system32\ping.exe' -n 1 127.0.0.1 
+         ~ 
Unexpected token '1' in expression or statement. 
At line:1 char:37 
+ 'C:\Windows\system32\ping.exe' -n 1 127.0.0.1 
+          ~~~~~~~~~ 
Unexpected token '127.0.0.1' in expression or statement. 
At line:1 char:1 
+ Invoke-Expression $cmd 
+ ~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : ParserError: (:) [Invoke-Expression], ParseException 
    + FullyQualifiedErrorId : UnexpectedToken,Microsoft.PowerShell.Commands.InvokeExpressionCommand 

PS C:\>$cmd = "& '$env:windir\system32\ping.exe' -n 1 127.0.0.1" 
PS C:\>$cmd 
& 'C:\Windows\system32\ping.exe' -n 1 127.0.0.1 
PS C:\>Invoke-Expression $cmd 

Pinging 127.0.0.1 with 32 bytes of data: 
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 

Ping statistics for 127.0.0.1: 
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss), 
Approximate round trip times in milli-seconds: 
    Minimum = 0ms, Maximum = 0ms, Average = 0ms

을 그냥뿐만 아니라 바로 호출 연산자를 사용하고 (Invoke-Expression을 완전히 도랑 수 있다는 것을 의미 이미 제안 된대로 @MartinBrandl).

$gitExe = "$env:ProgramFiles\Git\bin\git.exe" 
& $gitExe -c $solutionFolder 
+0

항상 좋은 대답입니다. –

3

첫째, 경로를 결합하는 Join-Path cmdlet을 사용하여 다음 &를 사용하여 git를 호출하고 매개 변수를 전달 것 다른 방법으로는 변수가 확장되지 않습니다.

+0

'$ gitExe' 변수 뒤에는 다른 것들이 있습니다. 예를 들어 :'$ gitExe add -f $ theFile' – Dov

+1

당신은 아마 모든 매개 변수를 해시 테이블에 저장하고 splatting을 사용하여'$ gitExe'에 전달해야합니다. –

1

사용 따옴표 :

$gitExe = "'$env:programfiles\Git\bin\git.exe' -C '$solutionFolder'" 

+1

그건'Invoke-Expression'과 함께 작동하지 않습니다. –

관련 문제