当前位置: 首页 > backend >正文

第18章|变量:把数据装进“盒子”的正确方式

第18章|变量:把数据装进“盒子”的正确方式(学习笔记 )

适用人群:PowerShell 新手到中级运维/开发,准备把“一次性命令”进化为可复用脚本的人。
目标:彻底理解变量、数组、双引号替换、转义、子表达式、类型约束,以及 v3+ 的自动展开(automatic unrolling)。


一、什么是变量?为何重要

  • 变量 = 有名字的内存盒子:把字符串、数字、对象集合、XML 等放进去,随时再取出来复用。
  • 弱声明、强能力:PowerShell 不要求预声明类型;但你可以显式指定类型来避免逻辑错误。
  • 对象世界:在 PowerShell 里“一切皆对象”,就连字符串也是 System.String

二、最常用的变量基本功

1)创建与读取

$var = "SERVER-R2"   # 赋值
$var                 # 读取
$var | Get-Member    # 看看这是哪种对象(类型/方法/属性)

2)在命令里使用变量

Get-WmiObject Win32_ComputerSystem -ComputerName $var

3)变量命名建议

  • 只用字母/数字/下划线,不要空格(真要用:${My Var})。
  • 名字要短而有义$computerName$services
  • 关闭会话变量即消失(非持久)。

三、引号的“魔法”:单引号、双引号、转义、子表达式

1)单引号 vs 双引号

  • 单引号原样字符串,不做变量替换。
  • 双引号:会做变量插值(替换)。
$computer = 'SERVER-R2'
$single   = 'computer is $computer'          # computer is $computer
$double   = "computer is $computer"          # computer is SERVER-R2

2)转义(重音符号 `)

  • 取消特殊意义:`$ 输出美元符号本体
  • 插入控制字符:`n 换行、`t 制表、`a 蜂鸣等
$phrase = "`$computer = $computer`nDone."

小贴士:用 Consolas 字体更容易区分 ` 与 ’ 。

3)子表达式 $()

  • 当插值里包含属性/索引/复杂表达式时,必须用 $()
$services  = Get-Service
$msg = "First service is $($services[0].Name)"

四、一次装很多:数组与集合

1)一次放入多个值

$computers = 'SRV1','SRV2','localhost'   # 数组
$computers.Count                         # 3
$computers[0]                            # SRV1
$computers[-1]                           # localhost(倒数第一个)

2)批量访问(v3+ 自动展开 / automatic unrolling)

v3 起:访问集合的属性会隐式枚举

$services = Get-Service
$services.Name      # 输出每个服务的 Name(v3+)

等价于:

Get-Service | Select-Object -ExpandProperty Name
# 或
Get-Service | ForEach-Object { $_.Name }

3)批量调用方法(通用写法)

$computers = 'SRV1','SRV2'
$computers = $computers | ForEach-Object { $_.ToLower() }   # 写回变量

五、强类型变量:让错误更早、更清楚

1)为什么要“上类型”

  • 避免把“100”当字符串拼接十次而不是做乘法。
[int]$number = Read-Host "Enter a number"  # 输入非数字会直接报错
$number = $number * 10

2)常见类型速查

  • [int]:整数
  • [single] / [double]:浮点
  • [string]:字符串
  • [char]:单个字符
  • [xml]:XML 文档(需有效 XML)
  • [adsi]:ADSI 查询句柄

3)重新指定类型

[int]$x = 5
# $x = "Hello"  # 会报错(无法转为 Int32)
[string]$x = "Hello"  # 重新声明为 string 后可赋值

六、变量相关 Cmdlet(知道即可)

  • Get-Variable / Set-Variable / New-Variable / Clear-Variable / Remove-Variable
  • 绝大多数场景,直接用 $var = ... 语法就好;Cmdlet 更多用于作用域元编程场景(参阅 about_Scope)。

七、最佳实践清单

  1. 命名简短有义,避免空格与晦涩缩写。
  2. 需要做算术或比较时,显式指定类型(如 [int])。
  3. 字符串插值:双引号 + $(),避免边界/索引解析错误。
  4. 集合访问优先用 v3+ 自动展开;跨版本脚本用 Select-Object -ExpandProperty 更通用。
  5. 修改数组元素请重新赋值或用 ForEach-Object 产生新集合再回写。
  6. 会话结束变量销毁;持久数据请落盘(CSV/Clixml/JSON)或存配置。

八、易错点速记

  • $ 不是变量名的一部分$var 的名字是 var
  • 双引号里写 $services[0].Name 必须 $() 包起来:$($services[0].Name)
  • v1/v2 不支持自动展开;团队混用版本时要注意兼容写法。
  • Read-Host 得到的是字符串;需要数值请加类型约束或转换。

九、练习题(带参考答案)

Q1: 写一行,把两台机器的 Win32_BIOS 查询结果放入变量 $bios
A:

$bios = Invoke-Command { Get-WmiObject Win32_BIOS } -ComputerName localhost, $env:COMPUTERNAME

Q2: 展示 $bios 并导出为 CliXML(保留对象结构)。
A:

$bios
$bios | Export-Clixml -Path .\bios.xml

Q3: 读入一个数字并安全乘以 10。
A:

[int]$n = Read-Host "Enter a number"
$n * 10

Q4: 将所有服务名拼接到一句话里,且首个服务名单独强调(正确使用子表达式)。
A:

$svcs = Get-Service
$msg  = "First is $($svcs[0].Name). All: $($svcs.Name -join ', ')"
$msg

Q5: 把数组 SRV1, SRV2, LOCALHOST 全部转小写并写回原变量。
A:

$computers = 'SRV1','SRV2','LOCALHOST'
$computers = $computers | ForEach-Object { $_.ToLower() }

十、常用片段收藏夹

# 1) 查看对象有哪些“能耐”
$var | Get-Member# 2) 读取服务列表并只取名字(v3+ 自动展开)
$services = Get-Service
$services.Name# 3) 双引号 + 子表达式:插值复杂表达式/索引
$msg = "Top service: $($services[0].Name)"# 4) 强类型输入,避免“100100100…”
[int]$count = Read-Host "Count?"
"*" * $count  # 正常乘法语义# 5) 把集合做一次变换再写回
$computers = $computers | ForEach-Object { $_.Trim().ToLower() }# 6) 导入/导出强类型对象(持久化)
$services | Export-Clixml .\services.xml
$back = Import-Clixml .\services.xml

十一、延伸阅读

  • Get-Help about_Variables
  • Get-Help about_Quoting_Rules(引号与转义)
  • Get-Help about_Escape_Characters
  • Get-Help about_Scope(变量作用域)
  • Get-Help Export-Clixml / Import-Clixml(对象持久化)

http://www.xdnf.cn/news/18844.html

相关文章:

  • 机器学习 TF-IDF方法
  • 【docker apoc 部署的neo4j安装apoc插件】
  • MySQL 面试题系列(五)
  • 【Kafka】重点概念和架构总结
  • Python 入门操作指南
  • 如何在 Docker 和AKS上使用 IIS
  • iOS技术之通过Charles抓包http、https数据
  • 【Linux】基本指令学习3
  • opencv+yolov8n图像模型训练和推断完整代码
  • Clerk 用户认证系统集成文档
  • ollama离线部署+大语言模型
  • AI-调查研究-62-机器人 机械臂五大应用场景详解:从焊接到手术,从农田到太空
  • 4步用代码拆解数学建模中的TOPSIS评价决策! ! !
  • Apache Commons Lang 3
  • 野火STM32Modbus主机读取寄存器/线圈失败(二)-解决CRC校验错误
  • uC/OS-III 队列相关接口
  • 数据分析与数据挖掘
  • 企业如何构建全面的高防IP防护体系?
  • Teams Workflows 业务流程搭建与Linux自动化运维拓展应用全解析
  • 状态设计模式
  • 构建面向人工智能决策的世界模型引擎所需的基本知识体系
  • 如何在GitHub找到10k+个stars的仓库
  • podman启动mongdb的container因为权限问题导致changing ownership和读取storage.bson失败的解决方法
  • CMake构建学习笔记20-iconv库的构建
  • 算法概述篇
  • 游戏空间划分技术
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段(20):文法+单词第7回2
  • 广告推荐模型1:逻辑回归(Logistic Regression,LR)
  • 如何拯救一家濒临破产的科技公司?
  • 技术总结:AArch64架构下Jenkins Agent(RPM容器编译节点)掉线问题分析与排查