【问题标题】:Powershell array scope; why is my array empty?Powershell 数组范围;为什么我的数组是空的?
【发布时间】:2013-12-29 12:50:06
【问题描述】:

我想要一个数组并从我的脚本中的不同函数中添加元素。我下面的示例说明了我可能对范围有误解的地方。我目前的理解是,如果在函数外部定义数组,然后在函数内部添加元素,那么这些元素应该在函数外部可用。

Function ListRunningServices
{
    $services+= Get-Service | ?{$_.Status -eq "Running"} | sort Name | select Name;
}

$services = @();
ListRunningServices;
$services;

我在这里缺少什么?也许我的风格完全错误。

【问题讨论】:

    标签: arrays powershell powershell-2.0


    【解决方案1】:

    您可以使用全局变量来解决这个问题,但使用全局变量通常被认为是不好的做法。如果您使用通用集合类型,例如 arraylist,而不是数组,那么您有一个 add() 方法,该方法将在父范围内更新集合,而无需在函数中显式地确定它的范围:

    Function ListRunningServices
    {
        Get-Service | ?{$_.Status -eq "Running"} | sort Name | select Name |
         ForEach-Object {$services.add($_)}
    }
    
    $services = New-Object collections.arraylist
    ListRunningServices
    $services
    

    【讨论】:

      【解决方案2】:

      功能块内的$services 作用于该功能。您可以改为执行以下操作:

      Function ListRunningServices {
          Get-Service | ?{$_.Status -eq "Running"} | sort Name | select Name
      }
      
      $services = ListRunningServices
      $services
      

      否则,您可以显式使用global: 来更改范围:

      Function ListRunningServices {
          $global:services = Get-Service | ?{$_.Status -eq "Running"} | sort Name | select Name
      }
      
      $services = @()
      ListRunningServices
      $services
      

      【讨论】:

      • 我想从脚本中的许多不同函数添加到服务数组。哪种方法是最好的做法?使用$global?
      • 如果可能,我会避免使用$global:。您是否有理由无法将 $services 作为参数提供给其他函数?了解您打算如何使用其他功能与 $services 交互可能会有所帮助。
      • 只是测试您发布的 $global 解决方案,它不会产生任何输出。
      • 我刚刚将第二个示例复制/粘贴到一个新的 PS 会话中,它会产生与第一个示例相同的输出。
      • 有趣,如果我粘贴到 Powershell 窗口中它可以工作,但如果我保存到文件中,然后使用 .\file.ps1 作为脚本调用该文件,我没有得到任何输出。
      【解决方案3】:

      函数范围内的$service与函数外的无关。

      试试:

      Function ListRunningServices
      {
          $services = @()
          $services+= Get-Service | ?{$_.Status -eq "Running"} | sort Name | select Name;
          return $services
      }
      
      
      $services = ListRunningServices
      $services
      

      保留您可以使用的大部分代码:

      Function ListRunningServices
      {
          $global:services+= Get-Service | ?{$_.Status -eq "Running"} | sort Name | select Name;
      }
      
      $services = @();
      ListRunningServices;
      $services;
      

      你可以在About_scope阅读完整的解释。

      【讨论】:

        【解决方案4】:

        Powershell 需要在 array 变量上指定带有 前缀scope。似乎“正常String”变量没有。像这样使用它们:

        # Visible everywhere inside the script file (f.ex: myNameScript.ps1)
        $script:names = @()
        
        Function AddStringToArray ([string]$i_name) {
            $script:names += $i_name
        }
        
        AddStringToArray -i_name "Markie"
        AddStringToArray -i_name "Harry"
        

        我知道这已经晚了,但我希望这至少对某人有所帮助。

        【讨论】:

          猜你喜欢
          • 2019-05-18
          • 2013-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多