Powershell 中的 $<drivename>:(例如`$code:`)是什么类型的对象? [英] What type of object is $<drivename>: (such as `$code:`) in Powershell?
问题描述
我今天在 Powershell 5.1 中使用选项卡自动完成作为变量名称,并注意到其中一个选项是 PSDrive 的名称.驱动器名称是 docs
,我想扩展名为 $document_name
.当我输入 $do
时,shell 确实将我输入的内容扩展为 $document_name
但由于某种原因,我输入了
第二次,此时扩展文本更改为 $docs:
.
I was using tab autocompletion for a variable name in Powershell 5.1 today and noticed that one of the choices was the name of a PSDrive. The drive name is docs
and I wanted to expand is called $document_name
. When I typed $do<tab>
, the shell did indeed expand what I had typed to $document_name
but for some reason, I typed <tab>
a second time and that's when the expanded text changed to $docs:
.
我进一步探索并发现我的每个 PSDrive 都存在这种类型的变量,或者至少标签扩展表明它确实存在.
I explored further and found that this type of variable exists for each of my PSDrives, or at least tab expansion suggests that it does.
更正式地说,对于每个 PSDrive PSD,标签扩展认为 $PSD:
是有效的.
More formally, for every PSDrive PSD, tab expansion believes that $PSD:
is a valid thing.
我的问题很简单:这些到底是什么?以下是我迄今为止所做的一些观察:
My question is simple: what the heck are these? Here are some observations I've made so far:
- 这些名称以
$
为前缀,因此它们看起来像 PS 变量.在本次讨论的其余部分(以及上面前面的讨论中),我将假设它们是变量并以此来引用它们. - 尽管它们看起来是变量,但它们不像大多数变量那样列在
Variable:
PSDrive 中.通过这种方式,它的行为类似于$env
变量",它也没有列在Variable:
中.我有一种感觉,如果我能找到关于$env
的文档,那么我也会理解这些对象. - 在某些方面,它们的行为类似于指向文件系统对象的指针.例如,如果文件名
readme.txt
包含文本Hello, world!"在名为code
的 PSDrive 上,则以下所有可能与 Powershell 进行交互.
- These names are prefixed with
$
, so they look like PS variables. For the rest of this discussion (and in the earlier discussion above), I will assume they are variables and refer to them as such. - Although they appear to be variables, they are not listed in the
Variable:
PSDrive like most variables. In this way, it behaves like the$env
"variable," which also is not listed inVariable:
. I have a feeling if I could find documentation about$env
, then I'd understand these objects also. - In some ways, they behave like pointers to filesystem objects. For example, if there is a file name
readme.txt
containing the text "Hello, world!" on a PSDrive namedcode
, then all of the following are possible interactions with Powershell.
获取文件的内容.
λ ${code:\readme.txt}
Hello, world!
只是为了证明上面结果的类型是String
:
Just to prove that the type of the above result is String
:
λ ${code:\readme.txt} | % { $_.GetType().Name }
String
尝试将其用作对 PSDrive 的引用对许多操作都不起作用,例如 cd
:
Trying to use this as a reference to the PSDrive doesn't work well for many operations, such as cd
:
C:\
λ cd ${code:}
At line:1 char:4
+ cd ${code:}
+ ~~~~~~~~
Variable reference is not valid. The variable name is missing.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidBracedVariableReference
我可以继续,但我被难住了.如果我将 $code:
(或 $env:
,就此而言)传递给 Get-Member
,我会收到一个错误消息,指出 变量引用无效
.
I could go on, but I'm stumped. If I pass $code:
(or $env:
, for that matter) to Get-Member
, I get an error saying Variable reference is not valid
.
那么$env
和$<PSDrive>:
之类的变量"到底是什么(例如$code:
)?它们是表情吗?内置表达式?某种对象?谢谢你的帮助.
So just what the heck are "variables" like $env
and $<PSDrive>:
(such as $code:
)? Are they expressions? Built-in expressions? Some kind of object? Thanks for any help.
推荐答案
你看到的是命名空间变量符号,这是一个基于变量的访问 PowerShell 驱动器中项目内容的方式,其底层提供程序实现了基于内容的访问(即实现了 IContentCmdletProvider
接口).
What you're seeing is namespace variable notation, which is a variable-based way to access the content of items in PowerShell drives whose underlying provider implements content-based access (i.e., implements the IContentCmdletProvider
interface).
一般语法是:
${<drive>:<path>} # same as: Get-Content <drive>:<path>
${<drive>:<path>} = ... # same as: Set-Content <drive>:<path> -Value ...
如果
名称和
都可以,则不需要封闭的 {...}
在语法上充当变量名;例如:
The enclosing {...}
aren't necessary if both the <drive>
name and the <path>
can syntactically serve as a variable name; e.g.:
$env:HOME # no {...} needed
${env:ProgramFiles(x86)} # {...} needed due to "(" and ")"
实际上,从 Windows PowerShell v5.1 开始,以下内置驱动器提供程序支持命名空间变量表示法:
In practice, as of Windows PowerShell v5.1, the following in-box drive providers support namespace variable notation:
- 环境(驱动
Env:
) - 函数(驱动
函数:
) - 别名(驱动器
别名:
) - 文件系统(驱动器
C:
, ...) - Variable (drive
Variable:
) - 尽管实际上毫无意义,因为省略驱动部分默认访问变量(例如,$variable:HOME
与刚刚$HOME
).
- Environment (drive
Env:
) - Function (drive
Function:
) - Alias (drive
Alias:
) - FileSystem (drives
C:
, ...) - Variable (drive
Variable:
) - though virtually pointless, given that omitting the drive part accesses variables by default (e.g.,$variable:HOME
is the same as just$HOME
).
其中,Env:
驱动器是迄今为止最常用于命名空间变量表示法的驱动器,尽管大多数用户不知道环境变量引用(例如 )的基础是什么$env:HOME
.
Of these, the Env:
drive is by far the most frequently used with namespace variable notation, even though most users aren't aware of what underlies an environment-variable references such as $env:HOME
.
有时您会看到它与文件系统驱动器一起使用 - 例如,${c:\foo\file.txt}
- 但事实上您只能使用 literal 路径以及您无法控制的字符编码限制了它的用途.
On occasion you see it used with a filesystem drive - e.g., ${c:\foo\file.txt}
- but the fact that you can only use literal paths and that you cannot control the character encoding limits its usefulness.
然而,它允许有趣的用途;例如:
It allows interesting uses, however; e.g.:
PS> $alias:foreach # Get the definition of alias 'foreach'
ForEach-Object
PS> $function:prompt # Get the body of the 'prompt' function
"PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) ";
# .Link
# https://go.microsoft.com/fwlink/?LinkID=225750
# .ExternalHelp System.Management.Automation.dll-help.xml
# Define a function foo that echoes 'hi' and invoke it.
PS> $function:foo = { 'hi' }; foo
hi
注意:
因为
${
和: } ${
> 等价于: } = Get-Content -Path
和: Set-Content -Path
,路径被解释为通配符表达式(因为这是: <value> -Path
所做的,而不是-LiteralPath
),这可能会导致看起来像通配符的路径出现问题 - 请参阅这个答案的示例和一种解决方法.
Because
${<drive>:<path>}
and${<drive>:<path>} = <value>
are equivalent toGet-Content -Path <drive>:<path>
andSet-Content -Path <drive>:<path> <value>
, paths are interpreted as wildcard expressions (because that's what-Path
does, as opposed to-LiteralPath
), which can cause problems with paths that look like wildcards - see this answer for an example and a workaround.
在撰写本文时,命名空间变量表示法尚未正式记录,但 this GitHub issue 建议这样做.
As of this writing, namespace variable notation isn't officially documented yet, but this GitHub issue suggests doing so.
这篇关于Powershell 中的 $<drivename>:(例如`$code:`)是什么类型的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!