web-dev-qa-db-fra.com

Invite de commandes Windows: comment obtenir la sortie d'une commande dans une variable d'environnement?

Je veux avoir une variable d'environnement qui contient le jour de la semaine dans cmd.exe.

Lorsque j'exécute cette commande, j'obtiens le résultat souhaité.

C:\Users\tisc> powershell (get-date).dayofweek
Friday

Ici, j'essaie de stocker le résultat dans une variable d'environnement.

C:\Users\tisc> set dow = powershell (get-date).dayofweek

Mais quand j'essaye de l'obtenir, je n'obtiens pas la chaîne comme je le voulais.

C:\Users\tisc> set dow
DoW=0
dow = powershell (get-date).dayofweek

Mon objectif est d'utiliser la variable dans un fichier batch pour certains scripts de sauvegarde.

60
Tim

Vous pouvez utiliser quelque chose comme:

$env:DOW = "foo"
89
Ion Todirel

Vous devez exécuter les deux commandes dans PowerShell car PowerShell est plus que capable de manipuler des variables d'environnement.

C'est à dire.:

$dow = (get-date).dayofweek
[Environment]::SetEnvironmentVariable("DOW", $dow, "Machine")

ou

[Environment]::SetEnvironmentVariable("DOW", $dow, "User")

Soit dit en passant, votre script ne fonctionne pas car tout ce que vous obtenez est le code retour PowerShell, pas les données qu'il produit. Il peut y avoir un moyen de le faire fonctionner, mais c'est finalement inutile par rapport à l'utilisation d'un script PowerShell approprié.

Pour être complet, voici un bel article de Microsoft sur PowerShell et les variables d'environnement:

Création et modification de variables d'environnement

Mise à jour: Après avoir examiné cette solution avec @ syneticon-dj dans le chat, il semble que le problème auquel vous êtes confronté en utilisant cette méthode est qu'une invite de commande doit être rechargée avant qu'il ne reflète les changements dans les variables environnementales qui se sont produits à l'extérieur.

Vous n'avez pas fourni beaucoup de détails sur ce que vous faites, mais si c'est la seule raison pour laquelle vous lancez PowerShell, ma suggestion serait de revoir comment vous faites les choses.

Soit l'ensemble de votre processus à l'aide de PowerShell ou avez-vous envisagé d'utiliser des tâches planifiées à la place? Vous pouvez planifier des tâches en fonction du jour de la semaine.

22
Dan

Je crois que la définition de la variable d'environnement depuis PowerShell avec [Environment]::SetEnvironmentVariable comme suggéré par Dan est inutile, car vous perdriez le contenu de la variable à la fin de PowerShell si vous choisissiez le contexte "processus" temporaire ou ne l'auriez pas dans l'environnement de votre fichier batch encore si vous avez choisi le contexte "machine" ou "utilisateur" permanent - c'est-à-dire, sauf si votre script entier est écrit dans PowerShell, où le problème ne se poserait pas en premier lieu:

C:\Users\myuser> echo %DOW%
%DOW%

C:\Users\myuser> powershell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. Alle Rechte vorbehalten.

PS C:\Users\myuser> $dow = (get-date).dayofweek
PS C:\Users\myuser> [Environment]::SetEnvironmentVariable("DOW", $dow, "User")
PS C:\Users\myuser> [Environment]::SetEnvironmentVariable("DOW", $dow, "Process")
PS C:\Users\myuser> exit

C:\Users\myuser> echo %DOW%
%DOW%

C:\Users\myuser>

Vous pouvez utiliser la commande for comme solution de contournement pour analyser la sortie de votre commande PowerShell et la placer dans une variable:

  for /F "usebackq tokens=1" %%i in (`powershell ^(get-date^).dayofweek`) do set DOW=%%i

Notez les caractères caret ^ utilisé pour échapper les caractères spéciaux entre parenthèses dans votre appel PowerShell.

Si vous le testez à partir de la ligne de commande et non à partir d'un contexte de fichier batch, vous devrez remplacer le %% avant les références de variable par %:

C:\Users\myuser> for /F "usebackq tokens=1" %i in (`powershell ^(get-date^).dayofw
eek`) do set DOW=%i

C:\Users\myuser> set DOW=Friday

C:\Users\myuser>
20
the-wabbit

Si c'était moi, et que le script parent a pour être un script Shell, je ferais juste une invocation effrontée de PowerShell dans le script .CMD comme:

set DOW=
for /f %%D in ('%SystemRoot%\System32\WindowsPowerShell\V1.0\powershell.exe -NoLogo -NoProfile -Command Write-Host -Object ^(Get-Date^).DayOfWeek;') do set DOW=%%D

Vous devrez peut-être vérifier votre stratégie d'exécution PowerShell (applet de commande Set-ExecutionPolicy).

4
Simon Catlin

Ou si vous êtes marié à faire cela dans l'ancien Shell, ignorez complètement PowerShell.

Utilisez la variable% date% et développez le jour à partir de l'abréviation qu'elle donne (cela peut être affecté par les paramètres régionaux de format de date):

C:\> echo %date%
Thu 09/05/2013

Prenez le premier jeton dans la réponse et développez-le:

C:\> type dayofweek.cmd
@echo off
for /f %%A in ("%date%") do set DAYOFWEEK=%%A
if "%DAYOFWEEK%" == "Mon" set DAYOFWEEK=Monday
if "%DAYOFWEEK%" == "Tue" set DAYOFWEEK=Tuesday
if "%DAYOFWEEK%" == "Wed" set DAYOFWEEK=Wednesday
if "%DAYOFWEEK%" == "Thu" set DAYOFWEEK=Thursday
if "%DAYOFWEEK%" == "Fri" set DAYOFWEEK=Friday
if "%DAYOFWEEK%" == "Sat" set DAYOFWEEK=Saturday
if "%DAYOFWEEK%" == "Sun" set DAYOFWEEK=Sunday
echo.%DAYOFWEEK%
C:\>
C:\> dayofweek
Thursday
3
M Jeremy Carter

Si vous souhaitez que votre fichier de commandes pour accéder aux variables d'environnement définies par une commande PowerShell s'exécute à partir de ce fichier de commandes, vous pouvez utiliser la solution de contournement suivante:

Faites que votre script PowerShell crée un fichier de sous-lots, mysub.bat, qui contient les lignes "set variable = value", et exécutez ce fichier de commandes mysub.bat à partir du fichier de commandes principal juste après la commande PowerShell.

Utilisez la méthode WriteAllLines plutôt que les méthodes de sortie PowerShell par défaut afin que le fichier de sous-lot ne soit pas généré avec le format de codage UTF-8.

Exemple

main.bat:

REM main.bat first line
powershell -Command "[System.IO.File]::WriteAllLines(\".\mysub.bat\", \"set VARIABLE=VALUE\");"
.\mysub.bat
echo VARIABLE=%VARIABLE%
REM expected output: VARIABLE=VALUE
1
user262456

En fait, lorsque vous placez quelque chose comme ci-dessous dans un fichier .ps1 (par exemple, t.ps1) et l'appeler à partir d'une session CMD avec PowerShell -File t.ps1 ... Ça marche bien.

$DateAndTime = (get-date -UFormat "%Y%m%d_%H%M%S")[Environment]::SetEnvironmentVariable("DateAndTime", $DateAndTime, "Machine")

Mais pas pour la session CMD à partir de laquelle le script t.ps1 a été appelé. Dans une nouvelle session CMD, nous obtenons:

D:> echo% DateAndTime% ==> 20120208_123106

Je suppose que nous devons trouver comment faire quelque chose comme export T=date dans une session CMD.

1
Edgar