Назад | Перейти на главную страницу

Командная строка Windows: как мне получить вывод команды в переменной среды?

Я хочу иметь переменную среды, которая содержит день недели в 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

Моя цель - использовать переменную в пакетном файле для некоторых сценариев резервного копирования.

Вы можете использовать что-то вроде:

$env:DOW = "foo"

Вы должны запустить обе команды в PowerShell, поскольку PowerShell более чем способен манипулировать переменными среды.

То есть:

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

или

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

Кстати, ваш скрипт не работает, потому что все, что вы получаете, - это код возврата PowerShell, а не данные, которые он производит. Возможно, есть способ заставить его работать, но в конечном итоге это бессмысленно по сравнению с простым использованием надлежащего сценария PowerShell.

Для полноты, вот хорошая статья от Microsoft о PowerShell и переменных окружения:

Создание и изменение переменных среды

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

Вы не предоставили много подробностей о том, что вы делаете, но если это единственная причина, по которой вы запускаете PowerShell, то мое реальное предложение - проверить, как вы это делаете.

Либо весь ваш процесс использует PowerShell, либо вы рассматривали возможность использования вместо этого запланированных задач? Вы можете планировать задачи в зависимости от дня недели.

Я считаю, что установка переменной среды из PowerShell с помощью [Environment]::SetEnvironmentVariable как предлагает Дэн, бессмысленно, потому что вы либо потеряете содержимое переменной при завершении 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>

Если бы это был я, а родительский скрипт имеет чтобы быть сценарием оболочки, я бы просто дерзко вызвал 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).

Или, если вы хотите делать это в старой оболочке, полностью пропустите 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

На самом деле, если поместить что-то подобное в файл .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.

Если вы хотите, чтобы ваш пакетный файл имел доступ к переменным среды, которые устанавливаются командой 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