У меня есть пакетный скрипт, который генерирует имя файла с отметкой даты для создания файла журнала через php. Это имя файла хранится в переменной пакетного файла Windows с именем logFile.
Я хотел бы повторно использовать переменную в моей команде piped tee, однако оказалось, что подкоманда, созданная в конвейере, не наследует и не имеет переменных из родительской консоли cmd в контексте.
Может кто-нибудь показать, как решить эту проблему без использования временных файлов или создания другого пакетного сценария?
Спасибо!
@echo off
SET logFile=| php -r "$d = new DateTime(); $dateString = $d->format('Ymd-His');
echo 'C:\\temp\\logs\\' . $dateString . '-exec.log';"
:: this is Ok
:: outputs c:\temp\logs\20150109-111031-exec.bat
%logFile%
:: This doesn't work
:: %logFile% in subCmd process is empty
:: how to inherit or pass environment/variable context to child processes?
call execJobs.bat | tee %logFile%
:: workaround, this doesn't work either
:: %logFile% is still empty in move command
:: call execJobs.bat | tee tmp
:: move /Y tmp %logFile%
:: del /F /Q tmp
C:\temp\logs\20150109-114443-exec.log
execJobs.bat | tee
В пакетных файлах «правильный» способ выполнить команду и извлечь ее вывод в переменную — это использовать for /f
команда
@echo off
setlocal enableextensions disabledelayedexpansion
set "logFile="
for /f "usebackq" %%a in (`
php -r "$d=new DateTime(); echo $d->format('Ymd-His');"`) do set "logFile=C:\temp\logs\%%a-exec.log"
echo %logFile%
for
Команда выполнит код в do
предложение для каждой строки в выводе команды execute. Сменный параметр (%%a
используется в этом случае) будет содержать содержимое обрабатываемой строки.
Проблема в том, что это
SET logFile=| php -r "$d = new DateTime(); $dateString = $d->format('Ymd-His');
echo 'C:\\temp\\logs\\' . $dateString . '-exec.log';"
на самом деле не делает то, что вы хотите; оператор pipe делит его на две команды, одна из которых удаляет logFile
переменная окружения, а другая из которых печатает имя файла.
это
%logFile%
ничего не делает, так как logFile
не определен и, следовательно, расширяется до пустой строки.
Вы думаете, что выход из расширения logFile
на самом деле идет от предыдущей команды.
Спасибо за комментарий, Гарри, MC, вы опередили меня, опубликовав решение. В этом есть смысл. Вот решение, если кто-то еще заинтересован. Добавление вывода команды в переменную оболочки не очень интуитивно понятно 🙂
:: this command places the output from the php script into a shell variable: logFile
for /f %%i in ('php -r "$d = new DateTime(); $dateString = $d->format('Ymd-His');
echo 'C:\\temp\\logs\\' . $dateString . '-exec.log';"') do set logFile=%%i
echo Logging execJobs.bat output to: %logFile%
echo.
call execJobs.bat | tee %logFile%
Я также собрал некоторую информацию из этого ответа:
Пакетное присвоение Windows вывода программы переменной