Командний рядок Windows: як я можу отримати висновок команди в змінну середовища?


59

Я хочу мати змінну середовища, яка містить день тижня в cmd.exe.

Коли я запускаю цю команду, я отримую потрібний результат.

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

Тут я намагаюся зберігати результат у змінній середовища.

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

Але коли я намагаюся отримати це, я не отримую струну так, як я хотів.

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

Моя мета - використовувати змінну у пакетному файлі для деяких резервних скриптів.

Відповіді:


87

Ви можете використовувати щось на кшталт:

$env:DOW = "foo"

3
Я не розумію, чому це було позначено негативно, чи знаєте ви краще встановити змінні середовища?
Іон Тодірел

2
+1 Це для мене чудово підходить для потрібного мені сценарію. PowerShell -Command $env:Note = 'Elevate'; (New-Object -com 'Shell.Application').ShellExecute('cmd.exe', '/k %*', '', 'runas')
Девід Руманн

14
@IonTodirel Тому що це зберігається лише в просторі процесу.
JohnD

нарешті, я тепер зрозумів, як встановити RAILS_ENV в powershell
wired00

А потім як ви виведете його, щоб переконатися, що він працював?
CodyBugstein

22

Вам слід запустити обидві команди в PowerShell, оскільки PowerShell більш ніж здатний маніпулювати змінними середовища.

Тобто:

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

або

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

До речі, ваш сценарій не працює, оскільки все, що ви отримуєте, - це код повернення PowerShell, а не дані, які він створює. Можливо, є спосіб змусити його працювати, але в кінцевому підсумку безглуздо в порівнянні з просто використанням правильного сценарію PowerShell.

Для повноти, ось приємна стаття від Microsoft про PowerShell та змінні середовища:

Створення та зміна змінних середовища

Оновлення: Переглянувши це рішення за допомогою @ syneticon-dj у чаті, виявляється, що проблема, з якою ви стикаєтесь за допомогою цього методу, полягає в тому, що командний рядок повинен бути перезавантажений, перш ніж він відображатиме зміни змінних умов середовища, що відбулися зовні.

Ви не надали багато деталей щодо того, що ви робите, але якщо це єдина причина, що ви запускаєте PowerShell, ніж моя фактична пропозиція переглянула б, як ви робите справи.

Або весь ваш процес, що використовує PowerShell, або ви замість цього планували використовувати заплановані завдання? Ви можете планувати завдання залежно від дня тижня.


Пакетний файл буде працювати щодня і запускається із запланованих завдань. Я думаю про те, щоб працювати в powerhell замість цього. Але я навіть більше новачка в powerhell, ніж cmd. І зараз у мене виникають труднощі з простою командою. Але я можу поставити нове запитання щодо цього, можливо, це для вас легке :) РЕДАКТУЙ: Я це зрозумів. Це було, як запустити програму з деякими параметрами.
Тім

Я теж не чудовий в PowerShell, але це варто вивчити. Для початку це краще майже будь-яким способом, але це також шлях Microsoft (І так інші виробники).
Дан

1
Також зауважте, що пропозиція @ Дана вище задає змінні середовища досить постійно (або в машинному, або в користувальницькому контексті). Якщо ви залишите третій параметр, ви можете встановити його лише для поточного процесу, який іноді є більш бажаним.
Пер Лундберг

20

Я вважаю , встановивши змінні оточення всередині PowerShell з [Environment]::SetEnvironmentVariableяк це було запропоновано Dan безглуздо, тому що ви або втратити вміст змінного по закінченню PowerShell , якщо ви вибрали тимчасовий «процес» контекст або не мати його в середовищі пакетної обробки файлу ще якщо ви вибрали постійний "машинний" або "користувальницький" контекст - тобто, якщо весь ваш скрипт не написаний у PowerShell, де проблема не виникне в першу чергу:

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>

Ви можете використовувати forкоманду як обхідний шлях для розбору результатів команди PowerShell і введення їх у змінну:

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

Зверніть увагу на символи карети, які ^використовуються для уникнення спеціальних символів у дужках під час виклику PowerShell.

Якщо ви тестуєте його з командного рядка, а не з контексту пакетного файлу, вам потрібно буде замінити %%попередні посилання змінної на %:

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>

Ні, це неправильно. Мій приклад нижче встановлює "звичайні" змінні середовища, які доступні з будь-якого пакетного файлу тощо.
День

@Dan Я вважаю, що ви помиляєтесь, я спробував налаштувати [Environment]::SetEnvironmentVariable("DOW", $dow, "user")в межах сеансу, що працює в повному обсязі, але він не був присутній у моєму батьківському сеансі cmd після припинення PowerShell
wabbit

Форматування це накрутило, але ви не визначили $ dow. Запуск мого прикладу в сценарії Powershell зберігає нормальну змінну навколишнього середовища, як очікувалося.
День

1
@Dan BTW: Я не проти прихильності, але слід зазначити, що продемонстрований підхід чітко робить те, про що запитував запитуючий, тому навіть якби був більш елегантний підхід, він все-таки буде правильним рішенням проблеми.
the wabbit

1
@ the-wabbit Це виглядає як нормальна поведінка в Windows. Навіть якщо ви оновлюєте глобальні змінні середовища, зміни будуть розпізнані лише з процесів, запущених після оновлення . Оскільки ви говорите про батьківський процес, він, мабуть, розпочався ще до зміни. Те саме відбувається з SETкомандним рядком. Спробуйте завести дитину, cmd.exeі ви побачите те саме. Однак поведінка, яку ви бачите в PowerShell, через те, що оновлення змінних оточуючих середовищ через .NET класи не впливає на поточний процес.
jpmc26

4

Якби це було мені, і батьківський сценарій повинен бути скрипт, я б просто зробити зухвалий виклик PowerShell в сценарії .CMD , як:

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

Можливо, вам доведеться перевірити політику виконання PowerShell (командлет Set-ExecutionPolicy).


3

Або якщо ви одружені, роблячи це в старій оболонці, повністю пропустіть PowerShell.

Використовуйте змінну% date% та розгорніть день за допомогою абревіатури, яку вона дає (на це можуть вплинути налаштування регіонального формату дати):

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

Візьміть перший маркер у відповіді та розгорніть на це:

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

1
Windows 10 не показуватиме ДОЛУ у% DATE%: H: \> echo% date% 20.03.2019
Рауль Салінас-Монтеагудо

1

Насправді, якщо помістити щось подібне нижче у файл .ps1 (скажімо, t.ps1) та викликати його з сеансу CMD з PowerShell -File t.ps1... це працює добре.

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

Але не для сеансу CMD, з якого викликано скрипт t.ps1. У новому сеансі CMD ми отримуємо:

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

Я думаю, ми повинні з'ясувати, як зробити щось подібне export T=dateна сесії CMD.


1

Якщо ви хочете, щоб ваш пакетний файл отримував доступ до змінних оточення, встановлених командою PowerShell, запускається з цього пакетного файлу, ви можете використовувати наступне вирішення:

Зробіть свій скрипт PowerShell створити файл mysub.batпідрядного пакету, що містить рядки "встановити змінну = значення", та виконайте цей пакетний файл mysub.bat з головного пакетного файлу відразу після команди PowerShell.

Використовуйте метод WriteAllLines, а не методи виводу PowerShell за замовчуванням, щоб субпакетний файл не генерувався у форматі кодування UTF-8.

Приклад

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.