为什么我的PowerShell引号没有正确转义

时间:2016-06-24 19:51:14

标签: visual-studio powershell nuget

我正在尝试将PowerShell变量分配给我想在别处调用的命令(Git命令)的一部分。我有这条线:

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

我期望产生这样的价值:

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

相反,当脚本运行时(作为Visual Studio 2015中NuGet包安装的一部分),我收到此错误:

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的新手,虽然我尝试了其他答案的建议,但我无法让它工作(所有不同类型的失败)。

3 个答案:

答案 0 :(得分:3)

首先,我将使用Join-Path cmdlet组合路径,然后使用git调用&并传递参数:

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

答案 1 :(得分:3)

AFAICS你的逃避并没有错,但你误解了Invoke-Expression的工作方式。 cmdlet提供了一种将给定字符串作为命令行运行的方法。但是,除非使用call operator"C:\Program Files\Git\bin\git.exe"),否则PowerShell不接受裸字符串(在您的情况下为&)作为命令行中的命令。相反,它会尝试回显字符串,但由于意外的令牌而失败:

演示:

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

答案 2 :(得分:1)

在双引号内使用单引号:

void setup() {
Serial.begin(9600);
}

bool dataRTP = false; // data ready to parse

void loop() {
  readSerial();
}

char message[64];
int index = 0;

void readSerial() {
  if (Serial.available() > 0)
    while (Serial.available() > 0)
      if (Serial.peek() != '#') // i'm using '#' as end of string declearation.
        message[index++] = Serial.read();
      else {
        message[index++] = '\n';
        dataRTP = true;
        break;
      }
  while (Serial.read() != -1) {} // flushing any possible characters off of
  if (dataRTP)                                              // UARTS buffer.
    parseMessage();
}

void parseMessage() {            // just testing here, actual code would be like :
  Serial.print(message);         // if (!strcmp(message, "this expression"))
  index = 0;                     //  callthisfunction();
  dataRTP = false;               // else ... etc
}

反过来说,变量不会被扩展。