通过脚本在环境变量范围内使用PowerShell的灵活性 [英] PowerShell flexibility in scope of environment variables via scripts

查看:77
本文介绍了通过脚本在环境变量范围内使用PowerShell的灵活性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在bash中,如果我在脚本内定义一个变量(例如 set_var.sh ),则可以选择在运行后这些定义是否仍然存在。剧本。
这将取决于我如何运行脚本,选项为:

In bash, if I define a variable inside a script (say, set_var.sh), I can choose whether those definitions persist after "running" the script. This will depend on how I "run" the script, the options being:


  1. sh set_var.sh (变量不持久)

  2. ./ set_var.sh (变量不持久,与第1点相同)

  3. source set_var.sh (变量仍然存在)

  1. sh set_var.sh (variables do not persist)
  2. ./set_var.sh (variables do not persist, same as point 1)
  3. source set_var.sh (variables persist)

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

This is irrespective from the variable being exported to the environment or not in set_var.sh.

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

Can the same as items 1 and 3 above be achieved with PowerShell 5.1 scripts, for both PS and $env variables?

有关示例,请参见下面的(1)。

For an illustration see (1) below.

编辑

根据Mathias R. Jessen的回答,等同于上述项目#3 点采购。
还有一个中间情况(上面没有指出,也许还有一种方法可以使它在bash中得到实现),其中环境变量仍然存在,而PS变量却没有。

As per answer by Mathias R. Jessen, the equivalent to item #3 above is "dot sourcing". There is also an "intermediate" case (not identified above, perhaps there is also a way to get this in bash), where environment variables persist but PS variables don't.

我的脚本:

# 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 ,其内容如下:

I have script set_var.sh with the following contents:

#!/bin/bash

export TEST_VAR=test_var
TEST_VAR2=test_var2

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

Then the following commands prove my point:

$ 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的有用答案

关于您的修改:

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

It is a script's direct invocation / invocation via & - which, unlike in sh / bash, runs in-process - preserves environment-variable changes, but not regular variables in the script.[1]

script块中使用& {...} )代替脚本文件进行简洁的演示:

Using & with a script block ({ ... }) in lieu of a script file for a succinct demonstration:

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*)




与PowerShell等效为1。( sh set_var.sh
和2。( ./ set_var.sh ):

显式调用PowerShell CLI Windows PowerShell中的 powershell.exe 在PowerShell [Core],v6 +版本中, pwsh ):需要在子进程 中运行脚本。

An explicit call to the PowerShell CLI (powershell.exe in Windows PowerShell, pwsh in PowerShell [Core], v6+): is needed to run a script in a child process.

注意:以下示例使用 pwsh ,但 powershell.exe 也是如此(其CLI与 pwsh ,仅向后者添加了一些参数。)

Note: The following examples use pwsh, but the same applies to powershell.exe (whose CLI is a mostly identical to pwsh's, with only a few parameters having been added to the latter).

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

In the simplest case, use -File (which is the implied parameter in PowerShell [Core], but is required in Windows PowerShell):

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

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

Note, however, that you'll only get textual output (strings) from the script this way rather than the rich objects that PowerShell normally supports.

接收对象的最简单方法-仅在 inside PowerShell中可用 [2] -是要传递一个脚本块 ,而不是在其中调用脚本,这将自动使CLI输出脚本输出对象的CLI输出XML序列化表示,并使这些表示成为

The simplest way to receive objects instead - available from inside PowerShell only[2] - is to pass a script block in which the script is called instead, which automatically makes the CLI output XML-serialized representations of the script's output objects, and causes these representations to be automatically deserialized by the calling session:

pwsh { .\set_var.ps1 } 

注意:


  • .\ 前缀是必需的,因为PowerShell(根据设计,作为安全功能)不允许运行纯文件名当前目录

  • The .\ prefix is necessary, because PowerShell - by design, as a security feature - does not permit running scripts by mere file name from the current directory.

使用CLIXML格式的基于XML的序列化-也用于PowerShell的远程处理和后台作业-对类型保真度有限制 ;除了.NET基本类型和一些众所周知的类型之外,您将获得原始对象的基于 [pscustomobject] approximations -请参见此答案

The XML-based serialization using the CLIXML format - which is also used for PowerShell's remoting and background jobs - has limits with respect to type fidelity; except for .NET primitive types and a handful well-known types, you get [pscustomobject]-based approximations of the original objects - see this answer.

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

[1] However, PowerShell does offer the ability to set variables across in-session scope boundaries, e.g. $global:foo = 'bar' to set a session-global variable or Set-Variable foo bar -Scope 1 to set a variable in the caller's (parent) scope (which when called from a script's top-level scope would also be the global scope).

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

[2] From outside of PowerShell, you can explicitly request output in CLIXML format (the XML-based object-serialization format), namely with the -of Xml CLI parameter, but you'll have to parse the XML yourself and reconstruct objects from it.

这篇关于通过脚本在环境变量范围内使用PowerShell的灵活性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆