本文介绍了Powershell中的$<drivename>:(如`$code:`)是什么类型的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天在 Powershell 5.1 中使用选项卡自动完成作为变量名,并注意到其中一个选项是 PSDrive 的名称.驱动器名称是 docs,我想扩展的名称是 $document_name.当我输入 $do<tab> 时,shell 确实将我输入的内容扩展为 $document_name 但出于某种原因,我输入了 <tab> 第二次,此时扩展文本变为 $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:.

我进一步探索发现,我的每个 PSDrives 都存在这种类型的变量,或者至少选项卡扩展表明它确实存在.

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 in Variable:. 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 named code, then all of the following are possible interactions with Powershell.

获取文件的内容.

λ  ${code:
eadme.txt}
Hello, world!

只是为了证明上面结果的类型是String:

Just to prove that the type of the above result is String:

λ  ${code:
eadme.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 ...

如果 <drive> 名称和 <path> 都可以,则不需要包含 {...}在语法上用作变量名;例如:

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:foofile.txt} - 但事实上您只能使用 literal 路径和你无法控制字符编码限制了它的用处.

On occasion you see it used with a filesystem drive - e.g., ${c:foofile.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

注意:

  • 因为 ${<drive>:<path>}${<drive>:<path>} = <value> 等价于
    Get-Content -Path <drive>:<path>Set-Content -Path <drive>:<path><value>,路径被解释为 通配符表达式(因为这是 -Path 所做的,而不是 -LiteralPath),这可能会导致看起来像通配符的路径出现问题 - 请参阅 this answer 示例和一种解决方法.

  • Because ${<drive>:<path>} and ${<drive>:<path>} = <value> are equivalent to
    Get-Content -Path <drive>:<path> and Set-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中的$&lt;drivename&gt;:(如`$code:`)是什么类型的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 17:39