2009-09-14 8 views
41

En Linux, que puedo hacer:Powershell: Configuración de una variable de entorno para un solo comando sólo

$ FOO=BAR ./myscript 

llamar "miscript" con la variable de entorno FOO está estableciendo.

¿Algo similar es posible en Powershell, es decir, sin tener que establecer primero la variable, llamar al comando y luego volver a desactivar la variable?

Para ser más claro sobre mi caso de uso, no quiero usar esto como parte de un script. Por el contrario, tengo un script de terceros cuyo comportamiento puedo controlar utilizando variables de entorno, pero, en este caso, no los argumentos de línea de comandos. Así que la posibilidad de alternar entre escribir

$ OPTION=1 ./myscript 

y

$ ./myscript 

sólo sería muy práctico.

+0

Creo que mi pregunta sería por qué se necesita para hacer esto? Yo pensaría que hay una mejor solución. – EBGreen

+6

No suele ser una pregunta útil, @EBGreen. El hecho de que la capacidad esté allí en shells de UNIX sugiere que hay un uso para ello. Fuera de lo común: controlar el nombre de usuario y la dirección de correo electrónico que git usa para commits. No existe una opción de línea de comandos para ellos; debe configurarlos en ~/.gitconfig, .git/config en cada repositorio o envars. De esas opciones, los envars son claramente más fáciles de establecer sobre la marcha (y convenientemente anulan los valores en los archivos). Entonces, si quiero cambiar el nombre de mi autor por un "commit git" en powershell, ¿cómo hacerlo? –

Respuesta

-3

Puede aplicar variables de ámbito a funciones y scripts.

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

Nueva variable también tiene un parámetro -scope si quieres ser formal y declarar la variable usando la nueva variable.

+0

Hmmm ... No creo que esta respuesta se aplique aquí. Las variables de PowerShell no son variables de entorno. Basado en la pregunta, el asker no está usando variables de entorno como espacio cero (como lo haría en CMD [si ese fuera el caso, esta respuesta se aplicaría]), pero necesita manipular el entorno antes de invocar un comando externo y luego restaurar el medio ambiente después (o algo por el estilo). – chwarr

16

En general, sería mejor pasar información al script a través de un parámetro en lugar de una variable global . Pero si eso es lo que hay que hacer y desea la limpieza automática de la variable a continuación, introducir un nuevo ámbito de esta manera:

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

Un par de cosas a tener en cuenta sobre esto. Primero, cuando se sale del alcance (scriptblock), $ foo ya no existe. Existía solo dentro del contexto del scriptblock. Sin embargo, la variable de entorno $ env: foo todavía existe porque eso realmente es un cambio global. Puede eliminar esa variable, así:

Remove-Item Env:\foo 
+1

Solo un pensamiento: ¿no podría generar un nuevo proceso de PowerShell, entregando el scriptblock a través del parámetro -Command? De esta forma, no tendrá que limpiar el entorno después, ya que estará contenido en el proceso secundario. Aunque estoy hablando con un MVP de PowerShell entonces esto probablemente no funciona :-) – Joey

+2

Keith, tenemos un bloque de entorno de empuje y un bloque de entorno emergente en Pscx para exactamente este escenario ;-) – x0n

+2

Johannes, eso funcionaría bien pero de alguna manera parece como hacer trampa :-) El PSCX Push/Pop-EnvironmentBlock (el * I * cambiado para que funcione de esta manera) funcionaría pero no tiene el soporte de limpieza automática que tiene un scriptblock. –

2

para lograr el equivalente de la sintaxis de Unix, que no sólo tiene que establecer la variable de entorno, pero hay que restablecer a su valor anterior después de ejecutar el comando. Lo he logrado para los comandos comunes que uso agregando funciones similares a las siguientes a mi perfil de Powershell.

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

Así que es un poco de mycmd ejecutable que funciona de forma diferente en función del valor de la variable de entorno app_master. Al definir cmd_special, ahora puedo ejecutar cmd_special desde la línea de comandos (incluidos otros parámetros) con la variable de entorno app_master establecida ... y se restablece (o incluso se desactiva) después de la ejecución del comando.

Presumiblemente, también podría hacer esto ad-hoc para una sola invocación.

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

En realidad debería ser más fácil que esto, pero parece que esto no es un caso de uso que está fácilmente el apoyo de PowerShell. Tal vez una versión futura (o función de un tercero) facilitará este caso de uso. Sería bueno si Powershell tuviera un cmdlet que hiciera esto, p.:

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

Tal vez un gurú PowerShell puede sugerir cómo se podría escribir un cmdlet tales.

0

me motivó lo suficiente sobre este problema que me fui por delante y escribió un guión para que: with-env.ps1

Uso:

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 

Por otro lado, si instala Gow puede utilizar env.exe cuales podría ser un poco más robusto que el script rápido que escribí arriba.

Uso:

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 
Cuestiones relacionadas