在PowerShell中,“.”运算符是什么作用?

40

这是个奇怪的问题。通常在 PowerShell 中执行外部命令时,我会使用 & 运算符,像这样:

& somecommand.exe -p somearguments

然而,今天我发现 . 运算符被这样使用:

.$env:systemdrive\chocolatey\chocolateyinstall\chocolatey.cmd install notepadplusplus

在这种情况下,句号起到什么作用?我不理解。


你的句号需要在后面加上一个空格,否则它会像下面提到的那样为对象属性添加“句点”。 - Vippy
  1. 这个点与对象属性无关。2) 不需要空格,因为 $env:systemdrive 是一个单一的词法标记,不同于 . 。3) 只有在 . 可被视为文件路径的一部分(通常是在后面跟随 \ )或命令名(如果后面跟随有效的命令/函数/文件/目录/驱动器名称字符)时,在前导 . 后才需要空格。
- Uber Kluger
5个回答

37

"." 点运算符 可以从其他已调用的脚本发送和接收变量。"&" 调用运算符 仅能发送变量。

例如,考虑以下内容:

脚本1 (call-operator.ps1):

clear

$funny = "laughing"

$scriptpath = split-path -parent $MyInvocation.MyCommand.Definition
$filename = "laughing.ps1"

"Example 1:" # Call another script. Variables are passed only forward.

& $scriptpath\$filename

"Example 2:" # Call another script. Variables are passed backwards and forwards.

. $scriptpath\$filename
$variableDefinedInOtherScript

脚本2(laughing.ps1):

# This is to test the passing of variables from call-operator.ps1

"I am $funny so hard. Passing variables is so hilarious."

$variableDefinedInOtherScript = "Hello World!"

创建两个脚本,只运行第一个脚本。您将看到“.”点源操作符发送和接收变量。

两者都有其用途,所以要有创意。例如,“&”调用操作符在你想要修改另一个脚本中的变量值而又保留当前脚本中原始值时非常有用。有点类似保险措施。 ;)


简而言之,这一切都与"作用域"有关。请前往谷歌搜索框并搜索"powershell 变量作用域"。 - Vippy

16

简短版:

.是一种特殊操作符,它可以实现普通操作符无法完成的任务。这个操作符有两种不同的用途。

详细版:

与任何其他语言一样,PowerShell脚本也支持许多不同类型的操作符来帮助操纵值。这些常规操作符包括:

  • 算术
  • 赋值
  • 比较
  • 逻辑
  • 重定向
  • 列表项
  • 拆分和连接
  • 类型
  • 一元

然而,PowerShell还支持称为特殊运算符的东西,用于执行其他类型的运算符无法执行的任务。

这些特殊运算符包括:

  • @() 数组子表达式运算符
  • & 调用运算符
  • [ ] 强制转换运算符
  • , 逗号运算符
  • . 点引用运算符
  • -f 格式化运算符
  • [ ] 索引运算符
  • | 流水线运算符
  • . 属性解引用运算符
  • .. 范围运算符
  • :: 静态成员运算符
  • $( ) 子表达式运算符

. 点引用运算符:在此上下文中,它允许脚本在当前作用域中运行,从而允许任何由脚本创建的函数、别名和变量添加到当前脚本中。

示例:

. c:\scripts.sample.ps1 

注意:在这种使用.特殊运算符的情况下,后面跟着一个空格以区分表示当前目录的符号 (.)。

示例:

. .\sample.ps1

.属性解引操作符:通过指示左侧表达式是一个对象,右侧表达式是对象的成员(属性或方法),允许访问跟随.的对象的属性和方法。

示例:

$myProcess.peakWorkingSet  
(get-process PowerShell).kill()

免责声明及来源:

在尝试扩展PowerShell脚本的功能集时,我遇到了同样的问题,并在查找答案时来到了这里。但是,我成功地使用Microsoft开发网络上的精彩写作和IT Pro的进一步扩展来找到了答案。

干杯。


6
点号是调用操作符:
$a = "Get-ChildItem" 
. $a # (executes Get-ChildItem in the current scope)

在您的情况下,我不知道它是做什么的。

7
微软创造的术语是“点号引用”(Dot Sourcing)。 - Filburt
4
对于CMD文件来说,无论是使用"."还是"&"符号都没有影响,因为CMD文件会在一个单独的进程(cmd.exe)中被执行。 - Keith Hill
这种点源的想法是改变作用域,使得脚本中创建的变量可以在全局范围内使用。不过就像Keith所说,cmd脚本无论如何都无法访问那个变量作用域,所以这并没有实际上改变任何东西。 - Jason Kelley
1
@Filburt 很不幸,该链接已过期。也许about_Scopes更适合。微软在那里称其为“点源符号”。 - Roi Danton

2

1
这个答案是为了稍微扩展一下David Brabant和他的评论者已经提供的内容。虽然那些评论都是正确和相关的,但是有一些被忽略了。
在调用外部命令时,OP使用&是不必要的。省略&不会对其使用示例产生任何影响。 &的目的是允许调用命令,其名称是(字符串)表达式的值。通过使用上面的&,powershell随后(基本上)将后续参数视为字符串,其中第一个参数是&正式调用的命令名称。如果省略&,powershell将采用行中的第一项作为要执行的命令。
然而,在第二个示例中,.是必需的(尽管其他人已经指出,在这种情况下,&同样有效)。如果没有它,命令行将以变量访问($env:systemdrive)开头,因此powershell将期望某种形式的表达式。但是,在变量引用之后紧接着的是裸文件路径,这不是一个有效的表达式,会生成错误。通过在行首使用.(或&),现在它被视为一个命令(因为开头看起来不像一个有效的表达式),并且参数被处理为可扩展字符串(" ")。因此,命令行被视为:
. "$env:systemdrive\chocolatey\chocolateyinstall\chocolatey.cmd" "install" "notepadplusplus"

第一个参数被替换为$env:systemdrive,然后.调用名为的程序。
注意:PowerShell如何处理命令行参数的完整描述比此处给出的要复杂得多。此版本已简化为仅包含回答问题所需的基本部分。请查看 about_Parsing以获取全面的说明。它不是完整的,但应涵盖大多数正常用法。还有其他关于堆栈溢出和GitHub(PowerShell现在驻留在其中)的帖子,涵盖了一些未列在官方文档中的看似古怪的行为。另一个有用的资源是 about_Operators,尽管这也不是完整的。例如,当调用除PowerShell脚本/ cmdlet之外的内容时,“。”和“&”的等效性根本没有提到。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接