bash - PowerShell 通过脚本在环境变量范围内的灵活性

标签 bash powershell variables scope environment-variables

在 bash 中,如果我在脚本中定义一个变量(例如,set_var.sh),我可以选择这些定义在“运行”脚本后是否保留。 这将取决于我如何“运行”脚本,选项是:

  1. sh set_var.sh(变量不持久化)
  2. ./set_var.sh(变量不持久化,同第1点)
  3. source set_var.sh(变量持久化)

这与是否在 set_var.sh 中导出到环境的变量无关。

对于 PS 和 $env 变量,是否可以使用 PowerShell 5.1 脚本实现与上述第 1 项和第 3 项相同的功能?

有关插图,请参见下面的 (1)。


编辑:

根据 Mathias R. Jessen 的回答,与上述第 3 项等效的是“点采购”。 还有一种“中间”情况(上面没有指出,也许还有一种方法可以在 bash 中实现),其中环境变量持续存在但 PS 变量不存在。

我的脚本:

# set_var.ps1
$env:TEST_VAR = 'test_var'
$TEST_VAR2 = 'test_var2'

我检查的内容:

> $env:TEST_VAR ; $TEST_VAR2 ;
> . .\set_var.ps1
> $env:TEST_VAR ; $TEST_VAR2 ;
test_var
test_var2
> Remove-Variable TEST_VAR2 ; Remove-Item env:TEST_VAR ;
> $env:TEST_VAR ; $TEST_VAR2 ;
> .\set_var.ps1
> $env:TEST_VAR ; $TEST_VAR2 ;
test_var
> Remove-Item env:TEST_VAR ;
> $env:TEST_VAR ; $TEST_VAR2 ;
> & .\set_var.ps1
> $env:TEST_VAR ; $TEST_VAR2 ;
test_var

(1) 持久/非持久变量示例

我有包含以下内容的脚本 set_var.sh:

#!/bin/bash

export TEST_VAR=test_var
TEST_VAR2=test_var2

然后下面的命令证明了我的观点:

$ echo $TEST_VAR ; echo $TEST_VAR2


$ sh set_var.sh ; echo $TEST_VAR ; echo $TEST_VAR2


$ source set_var.sh ; echo $TEST_VAR ; echo $TEST_VAR2
test_var
test_var2
$ echo $TEST_VAR ; echo $TEST_VAR2
test_var
test_var2
$ env | grep TEST_VAR
TEST_VAR=test_var
$ unset TEST_VAR ; unset TEST_VAR2
$ echo $TEST_VAR ; echo $TEST_VAR2


$ ./set_var.sh ; echo $TEST_VAR ; echo $TEST_VAR2


$ echo $TEST_VAR ; echo $TEST_VAR2


最佳答案

补充Mathias' helpful answer :

关于您的修改:

这是脚本的直接调用/通过&调用 - 这与 sh 不同/bash ,运行进程中 - 保留环境变量更改,但不保留脚本中的常规变量。[1]

使用 &使用脚本 block ( { ... } ) 代替脚本文件进行简洁演示:

PS> & { $foo = 'bar'; $env:foo = 'bar-env' }; "[$foo]", "[$env:foo]"
[]        # regular variable in the script [block] scope went out of scope
[bar-env] # environment variable is visible to caller (the whole *process*)

至于 1 的 PowerShell 等价物。 ( sh set_var.sh ) 和 2. ( ./set_var.sh ):

对 PowerShell CLI 的显式调用(Windows PowerShell 中的 powershell.exe ,PowerShell [Core] 中的 pwsh ,v6+):需要在 子进程

注意:以下示例使用pwsh , 但同样适用于 powershell.exe (其 CLI 与 pwsh 基本相同,只是向后者添加了一些参数)。

在最简单的情况下,使用 -File (这是 PowerShell [Core] 中的隐含参数,但在 Windows PowerShell 中是必需的):

pwsh -File set_var.ps1  # PowerShell v6+: same as: pwsh set_var.ps1

但是请注意,您只能通过这种方式从脚本中获得文本输出(字符串),而不是丰富的对象 PowerShell 通常支持。

接收对象的最简单方法 - 仅可从 内部 PowerShell[2] 获取 - 是传递一个脚本 block ,在其中调用脚本,这会自动使 CLI 输出脚本输出对象的 XML 序列化表示,并导致这些表示自动反序列化通过调用 session :

pwsh { .\set_var.ps1 } 

注意:

  • .\前缀是必需的,因为 PowerShell - 按照设计,作为一项安全功能 - 不允许从当前目录 仅文件名 运行脚本。

  • 使用 CLIXML 格式的基于 XML 的序列化(也用于 PowerShell 的远程处理和后台作业)类型保真度方面有限制;除了 .NET 基本类型和少数知名类型外,您会得到 [pscustomobject] - 基于原始对象的近似值 - 参见this answer .


[1] 但是,PowerShell 确实提供了跨 session 范围边界设置变量的能力,例如$global:foo = 'bar'设置 session 全局变量或 Set-Variable foo bar -Scope 1调用者(父级)范围内设置一个变量(从脚本的顶级范围调用时也将是全局范围)。

[2] 从 PowerShell 外部,您可以明确请求 CLIXML 格式(基于 XML 的对象序列化格式)的输出,即 -of Xml CLI 参数,但您必须自己解析 XML 并从中重建对象。

关于bash - PowerShell 通过脚本在环境变量范围内的灵活性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62932372/

相关文章:

linux - Grep 递归和计数

linux - 如何从没有 $ 符号的代码片段中复制 bash 命令?

json 文件到 powershell 并返回到 json 文件

regex - Powershell:Get-EventLog 输出上的正则表达式并找到最大数

regex - 选择字符串以仅显示返回行的特定部分

python - 在Python中,可以从静态方法引用实例变量吗?

java - 有没有办法让@PersistenceContext 变得灵活?

python - 如何处理python 3中的错误 "too many arguments"

linux - ulimit - help 和 man bash 提到的不同选项

mysql - 编辑 Bash 脚本以显示输出