gpt4 book ai didi

powershell - 如何在 Powershell 中分配和引用包含方括号的环境变量

转载 作者:行者123 更新时间:2023-12-03 23:52:30 25 4
gpt4 key购买 nike

当未指定 PSDrive 时,以下工作:

${[foo]}="bar"
echo ${[foo]}

但是下面的不行

$env:${[foo]}="bar"
At line:1 char:1
+ $env:${[foo]}="bar"
+ ~~~~~
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using ${} to delimit the name.
At line:1 char:6
+ $env:${[foo]}="bar"
+ ~~~~~~~~~~~~~~
Unexpected token '${[foo]}="bar"' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidVariableReferenceWithDrive
${env:[foo]}="bar"
Cannot find path 'env:[foo]' because it does not exist.
At line:1 char:1
+ ${env:[foo]}="bar"
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (env:[foo]:String) [], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound

以下工作,但我很好奇是否有简写语法:

Set-Item -LiteralPath env:${[foo]} -Value "bar"
Get-Item -LiteralPath env:${[foo]} | % {$_.Value}

但是以下不起作用:

Set-Item -LiteralPath env:${[foo]2} -Value "bar"
Set-Item : Cannot process argument because the value of argument "name" is null. Change the value of argument "name" to a non-null value.
At line:1 char:1
+ Set-Item -LiteralPath env:${[foo]2} -Value "bar"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:String) [Set-Item], PSArgumentNullException
+ FullyQualifiedErrorId : SetItemNullName,Microsoft.PowerShell.Commands.SetItemCommand

最佳答案

从 PowerShell Core 6.2.0 开始编写

原因是 PowerShell 处理以下内容:

${<drive>:<name>}

就好像你指定了:

Get-Content -Path <drive>:<name>  # or, with assignment, Set-Content -Path ...

此表示法 - 虽然经常与 Env: 一起使用驱动器(例如,$env:Path)- 作为名为命名空间变量表示法通用范例 鲜为人知,这在 this answer 中有解释。 .

问题是使用 -Path而不是 -LiteralPath ,因为 -Path 将其参数解释为通配符表达式

因此,[foo]${env:[foo]} - 而不是按原样使用 - 被解释为匹配 单个 字符的通配符表达式,该字符是 fo ( [foo] 是一个字符集或范围 ( [...] ),它匹配内部的任何一个(不同的)字符 - 请参阅 about_Wildcards

关于分配${env:[foo]} , Set-Content -Path 的逻辑要求基于通配符的路径解析为现有的东西,即使您通常不需要显式创建环境变量;例如,${env:NoSuchVarExistsYet} = 'new'工作得很好。


解决方法:

使用(!)- ` -转义通配符元字符:

# Namespace variable notation only works with if you
# double(!)-backtick-escape the wildcard metacharacters:

# Assign to / implicitly create env. var '[foo]'
${env:``[foo``]} = 'bar'

# Get its value.
${env:``[foo``]}

注意:

  • 根本不需要转义,因为没有充分的理由将概念上标识给定的已知项的路径视为通配符表达式 - 参见 GitHub issue #9225 .

  • 那个加倍 ` - 需要转义是一个额外的怪癖 - 请参阅 GitHub issue #7999 .

  • 另一种解决方法 - 一种不涉及转义的方法 - 是使用
    Set-Content -LiteralPath env:[foo] barGet-Content -LiteralPath env:[foo] ,但这既冗长又缓慢。


至于您尝试过的其他语法变体:

$env:${[foo]}="bar"

因为您的变量引用不是 {...} -封闭作为一个整体(除了开头的$),:之后的记号只允许包含不需要转义的字符 - 和$ , {}都违反了这条规则。

  • {...} - 包含整个路径 - ${env:[foo]} - 解决了语法问题,但遇到了上面详述的问题。

Set-Item -LiteralPath env:${[foo]} -Value "bar"

这通常有效,因为字符串扩展在这里是预先应用的——就好像你已经通过了"env:${[foo]}" :对名为 ${[foo]} 的(常规)变量的引用被扩展(替换为它的值)并且实际上附加到文字 env: , before 将结果交给 Set-Item .

如果这样的常规变量不存在,那会怎样Set-Item看到的只是env: (因为不存在的变量默认为 $null ,在字符串上下文中变成空字符串),这会由于缺少变量名而导致错误。

相比之下,以下将设置一个名为 unrelated 的环境变量相反:

# Create a regular variable literally named '[foo]'.
${[foo]} = 'unrelated'

# !! The following sets env:unrelated, i.e., env. var 'unrelated',
# !! due to the string expansion that is performed on the -LiteralPath
# !! argument up front.
Set-Item -LiteralPath env:${[foo]} bar

$env:unrelated # -> 'bar'

同样适用于Get-Item -LiteralPath env:${[foo]}
Set-Item -LiteralPath env:${[foo]2} -Value "bar" .

关于powershell - 如何在 Powershell 中分配和引用包含方括号的环境变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55343828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com