web-dev-qa-db-fra.com

Powershell: Définition d'une variable d'environnement pour une seule commande

Sur Linux, je peux faire:

$ FOO=BAR ./myscript

appeler "myscript" avec la variable d'environnement FOO en cours de définition.

Est-ce que quelque chose de similaire est possible dans Powershell, c'est-à-dire sans avoir à définir d'abord la variable, appeler la commande, puis redéfinir la variable?

Pour être plus clair sur mon cas d'utilisation, je ne veux pas l'utiliser dans le cadre d'un script. J'ai plutôt un script tiers dont je peux contrôler le comportement à l'aide de variables d'environnement, mais, dans ce cas, pas d'arguments de ligne de commande. Donc, être capable d'alterner entre la frappe

$ OPTION=1 ./myscript

et 

$ ./myscript

serait juste très pratique.

55
miracle2k

En règle générale, il serait préférable de transmettre les informations au script via un paramètre plutôt que par une variable globale (.) . Mais si c'est ce que vous devez faire, vous pouvez le faire de cette façon:

$env:FOO = 'BAR'; ./myscript

La variable d'environnement $ env: FOO peut être supprimée ultérieurement, comme ceci:

Remove-Item Env:\FOO
23
Keith Hill

Pour obtenir l'équivalent de la syntaxe Unix, vous devez non seulement définir la variable d'environnement, mais vous devez également rétablir sa valeur antérieure après l'exécution de la commande. J'ai accompli cela pour les commandes courantes que j'utilise en ajoutant des fonctions similaires à ce qui suit dans mon profil powershell.

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

Donc mycmd est un exécutable qui fonctionne différemment selon la valeur de la variable d'environnement app_master. En définissant cmd_special, je peux maintenant exécuter cmd_special à partir de la ligne de commande (y compris d'autres paramètres) avec la variable d'environnement app_master définie ... et il est réinitialisé (ou même non défini) après l'exécution de la commande.

Vraisemblablement, vous pourriez aussi faire cela ad-hoc pour une invocation unique.

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

Cela devrait vraiment être plus facile que cela, mais apparemment, ce n’est pas un cas d’utilisation facilement pris en charge par powershell. Une version future (ou une fonction tierce) facilitera peut-être ce cas d'utilisation. Ce serait bien si Powershell avait une applet de commande qui le ferait, par exemple:

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

Un gourou de Powershell peut peut-être suggérer comment on pourrait écrire une telle applet de commande.

2
Jason R. Coombs

Je me suis suffisamment motivé pour résoudre ce problème et j'ai donc écrit un script pour le résoudre: 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

D'autre part, si vous installez Gow , vous pouvez utiliser env.exe, qui est peut-être un peu plus robuste que le script rapide que j'ai écrit ci-dessus.

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
2
kizzx2

Étant donné que CMD est la CLI native du noyau Windows (et demeure l'interface d'automatisation de nombreux outils), vous pouvez exécuter votre script PowerShell avec powershell.exe à partir de l'invite CMD ou une interface acceptant les instructions de la console CMD.

Si vous utilisez le paramètre -File pour transmettre votre script à powershell.exe, aucun autre code PowerShell ne peut être utilisé pour définir une variable d'environnement à laquelle le script doit accéder. Vous pouvez donc définir vos variables d'environnement dans l'environnement CMD avant d'appeler powershell.exe:

> set foo=bar && powershell.exe -File .\script.ps1

Un seul & fonctionnera aussi, mais permettra à la commande de continuer si la set échoue pour une raison quelconque. (Est-ce même possible? Je n'en ai aucune idée.)

En outre, il peut être plus prudent de mettre "foo=bar" entre guillemets afin que rien de ce qui suit ne soit transmis à set en tant que contenu de la variable.

0
NReilingh