Powershell:仅为单个命令设置环境变量

时间:2022-06-01 16:39:19

On Linux, I can do:

在Linux上,我可以这样做:

$ FOO=BAR ./myscript

to call "myscript" with the environment variable FOO being set.

在设置环境变量FOO的情况下调用“myscript”。

Is something similar possible in Powershell, i.e. without having to first set the variable, call the command, and then unset the variable again?

在Powershell中是否有类似的可能,即无需先设置变量,调用命令,然后再次取消设置变量?

To be more clear about my use case - I don't want to use this as part of a script. Rather, I have a third party script whose behavior I can control using environment variables, but, in this case, not command line arguments. So being able to alternate between typing

为了更清楚我的用例 - 我不想将它作为脚本的一部分使用。相反,我有一个第三方脚本,我可以使用环境变量控制其行为,但在这种情况下,不是命令行参数。因此能够在打字之间交替

$ OPTION=1 ./myscript

and

$ ./myscript

would just be very handy.

会非常方便。

4 个解决方案

#1


20  

Generally it would be better to pass info to the script via a parameter rather than a global variable. But if that is what you need to do and you want automatic cleanup of the variable then introduce a new scope like so:

通常,最好通过参数而不是全局变量将信息传递给脚本。但是,如果这是你需要做的,你想要自动清理变量,那么引入一个新的范围,如下所示:

& { $foo = 'bar'; $env:foo = 'bar'; ./myscript }

A couple of things to note about this. First, when the scope (scriptblock) is exited, $foo no longer exists. It existed only within the context of the scriptblock. However the environment variable $env:foo still exists because that truly is a global change. You can delete that variable like so:

关于这一点需要注意几点。首先,当退出范围(scriptblock)时,$ foo不再存在。它仅存在于scriptblock的上下文中。但是环境变量$ env:foo仍然存在,因为它确实是一个全局变化。您可以删除该变量,如下所示:

Remove-Item Env:\foo

#2


2  

To accomplish the equivalent of the Unix syntax, you not only have to set the environment variable, but you have to reset it to its former value after executing the command. I've accomplished this for common commands I use by adding functions similar to the following to my powershell profile.

要完成Unix语法的等效,您不仅需要设置环境变量,还必须在执行命令后将其重置为以前的值。我已经通过在PowerShell配置文件中添加类似于以下功能的常用命令来完成此操作。

function cmd_special()
{
  $orig_master=$env:app_master
  $env:app_master='http://host.example.com'
  mycmd $args
  $env:app_master=$orig_master
}

So mycmd is some executable that operates differently depending on the value of the environment variable app_master. By defining cmd_special, I can now execute cmd_special from the command line (including other parameters) with the app_master environment variable set... and it gets reset (or even unset) after execution of the command.

所以mycmd是一些可执行文件,它根据环境变量app_master的值进行不同的操作。通过定义cmd_special,我现在可以使用app_master环境变量set从命令行执行cmd_special(包括其他参数),并在执行命令后重置(甚至取消设置)。

Presumably, you could also do this ad-hoc for a single invocation.

据推测,您也可以对单个调用进行临时处理。

& { $orig_master=$env:appmaster; $env:app_master='http://host.example.com'; mycmd $args; $env:app_master=$orig_master }

It really should be easier than this, but apparently this isn't a use-case that's readily supported by powershell. Maybe a future version (or third-party function) will facilitate this use-case. It would be nice if Powershell had a cmdlet that would do this, e.g.:

它应该比这更容易,但显然这不是PowerShell容易支持的用例。也许未来版本(或第三方功能)将促进此用例。如果Powershell有一个可以执行此操作的cmdlet,那将是很好的,例如:

with-env app_master='http://host.example.com' mycmd

Perhaps a Powershell guru can suggest how one might write such a cmdlet.

也许Powershell大师可以建议如何编写这样的cmdlet。

#3


1  

I got motivated enough about this problem that I went ahead and wrote a script for it: with-env.ps1

我对这个问题充满了动力,我继续为它写了一个脚本:with-env.ps1

Usage:

用法:

with-env.ps1 FOO=foo BAR=bar your command here

# Supports dot-env files as well
with-env.ps1 .\.env OTHER_ENV=env command here

On the other hand, if you install Gow you can use env.exe which might be a little more robust than the quick script I wrote above.

另一方面,如果你安装Gow,你可以使用env.exe,这可能比我上面写的快速脚本更强大。

Usage:

用法:

env.exe FOO=foo BAR=bar your command here

# To use it with dot-env files
env.exe $(cat .env | grep.exe -v '^#') SOME_OTHER_ENV=val your command

#4


-3  

You can scope variables to functions and scripts.

您可以将变量范围限定为函数和脚本。

$script:foo = "foo"
$foo
$function:functionVariable = "v"
$functionVariable

New-Variable also has a -scope parameter if you want to be formal and declare your variable using new-variable.

如果你想要正式并且使用new-variable声明你的变量,New-Variable也有一个-scope参数。

#1


20  

Generally it would be better to pass info to the script via a parameter rather than a global variable. But if that is what you need to do and you want automatic cleanup of the variable then introduce a new scope like so:

通常,最好通过参数而不是全局变量将信息传递给脚本。但是,如果这是你需要做的,你想要自动清理变量,那么引入一个新的范围,如下所示:

& { $foo = 'bar'; $env:foo = 'bar'; ./myscript }

A couple of things to note about this. First, when the scope (scriptblock) is exited, $foo no longer exists. It existed only within the context of the scriptblock. However the environment variable $env:foo still exists because that truly is a global change. You can delete that variable like so:

关于这一点需要注意几点。首先,当退出范围(scriptblock)时,$ foo不再存在。它仅存在于scriptblock的上下文中。但是环境变量$ env:foo仍然存在,因为它确实是一个全局变化。您可以删除该变量,如下所示:

Remove-Item Env:\foo

#2


2  

To accomplish the equivalent of the Unix syntax, you not only have to set the environment variable, but you have to reset it to its former value after executing the command. I've accomplished this for common commands I use by adding functions similar to the following to my powershell profile.

要完成Unix语法的等效,您不仅需要设置环境变量,还必须在执行命令后将其重置为以前的值。我已经通过在PowerShell配置文件中添加类似于以下功能的常用命令来完成此操作。

function cmd_special()
{
  $orig_master=$env:app_master
  $env:app_master='http://host.example.com'
  mycmd $args
  $env:app_master=$orig_master
}

So mycmd is some executable that operates differently depending on the value of the environment variable app_master. By defining cmd_special, I can now execute cmd_special from the command line (including other parameters) with the app_master environment variable set... and it gets reset (or even unset) after execution of the command.

所以mycmd是一些可执行文件,它根据环境变量app_master的值进行不同的操作。通过定义cmd_special,我现在可以使用app_master环境变量set从命令行执行cmd_special(包括其他参数),并在执行命令后重置(甚至取消设置)。

Presumably, you could also do this ad-hoc for a single invocation.

据推测,您也可以对单个调用进行临时处理。

& { $orig_master=$env:appmaster; $env:app_master='http://host.example.com'; mycmd $args; $env:app_master=$orig_master }

It really should be easier than this, but apparently this isn't a use-case that's readily supported by powershell. Maybe a future version (or third-party function) will facilitate this use-case. It would be nice if Powershell had a cmdlet that would do this, e.g.:

它应该比这更容易,但显然这不是PowerShell容易支持的用例。也许未来版本(或第三方功能)将促进此用例。如果Powershell有一个可以执行此操作的cmdlet,那将是很好的,例如:

with-env app_master='http://host.example.com' mycmd

Perhaps a Powershell guru can suggest how one might write such a cmdlet.

也许Powershell大师可以建议如何编写这样的cmdlet。

#3


1  

I got motivated enough about this problem that I went ahead and wrote a script for it: with-env.ps1

我对这个问题充满了动力,我继续为它写了一个脚本:with-env.ps1

Usage:

用法:

with-env.ps1 FOO=foo BAR=bar your command here

# Supports dot-env files as well
with-env.ps1 .\.env OTHER_ENV=env command here

On the other hand, if you install Gow you can use env.exe which might be a little more robust than the quick script I wrote above.

另一方面,如果你安装Gow,你可以使用env.exe,这可能比我上面写的快速脚本更强大。

Usage:

用法:

env.exe FOO=foo BAR=bar your command here

# To use it with dot-env files
env.exe $(cat .env | grep.exe -v '^#') SOME_OTHER_ENV=val your command

#4


-3  

You can scope variables to functions and scripts.

您可以将变量范围限定为函数和脚本。

$script:foo = "foo"
$foo
$function:functionVariable = "v"
$functionVariable

New-Variable also has a -scope parameter if you want to be formal and declare your variable using new-variable.

如果你想要正式并且使用new-variable声明你的变量,New-Variable也有一个-scope参数。