2

当我从新打开的 PowerShell 控制台运行以下脚本时,循环退出,因此显然存在匹配,但 $matches 变量(因此 $matches.PORT)第一次没有填充。当脚本再次运行时,它会被填充。

./ssh.ps1

$BLOCK = { az webapp create-remote-connection --subscription <MY-SUBSCRIPTION> --resource-group <RESOURCE-GROUP> -n <NAME> }
$global:CONNECTION = Start-ThreadJob -ScriptBlock $BLOCK

$done = 0
$match_string = ".*Opening tunnel on port: (?<PORT>\d{1,5})\b.*"

while ($done -lt 1) {
    if ($CONNECTION.HasMoreData)
    {
        $DATA = Receive-Job $CONNECTION 2>&1
        
        if ($DATA -match $match_string)
        {
            $port = $matches.PORT
            Write-Output "Connection open on port $port."
            $done = 1
        }
    }
}
Write-Output "Loop ended."
exit

PowerShell 控制台中的输出是:

PS <LOCAL-DIR>> ./ssh
Connection open on port .
Loop ended.
PS <LOCAL-DIR>> ./ssh
Connection open on port 63182.
Loop ended.

相比之下,当我尝试运行以下脚本时,$matches 在第一次运行时会被填充。

./match.ps1

$string1 = "hello, hello, you big beautiful world of wonder!"
$match_str = ".*\b(?<gotcha>world)\b.*"

$done = 0

while ($done -lt 1)
{
    if ($string1 -match $match_str)
    {
        write-output "Matches:"
        write-output $matches
        
        $done = 1
    }
}

输出:

PS <LOCAL-DIR>> ./match
Matches:

Name                           Value
----                           -----
gotcha                         world
0                              hello, hello, you big beautiful world of wonder!

如果有人能理解为什么在没有填充 $matches 的情况下在第一个脚本中匹配文本,我将非常感激。

PS循环后存在的脚本仅用于调查目的,而不是我的代码实际执行的操作。

PPS 作为参考,az webapp create-remote-connection在连接延迟后,来自 的输出为:

Verifying if app is running....
App is running. Trying to establish tunnel connection...
Opening tunnel on port: 63341
SSH is available { username: root, password: Docker! }
Ctrl + C to close

(端口每次都不同。)

4

1 回答 1

3

如果在操作后填充自动$Matches变量 ,则暗示 LHS 操作数是一个集合而不是单个字符串-match

因此,循环遍历每行的值$DATA并分别匹配:

foreach ($line in $DATA) {
  if ($line -match $match_string)
  {
    $port = $matches.PORT
    "Connection open on port $port."
    $done = 1
    break
  }
}

按设计:

  • $Matches仅当 LHS 是字符串(标量)时才会填充。
  • 使用集合(数组)作为 LHS,-match- 与许多比较运算符一样 - 充当过滤器并返回匹配元素的(可能为空的)子数组
  • 如果给定的字符串标量操作碰巧找不到匹配项或其LHS 是一个集合,则任何先前 $Matches的值都会保留-match
于 2021-11-12T23:04:41.407 回答