Переменные не разбираются в командах - PullRequest
1 голос
/ 22 июня 2011

У меня есть командный файл windows cmd, который использует переменную, но везде, где эта переменная используется после ее установки, происходит сбой.

Вот мой пакетный скрипт:

@echo off

if exist Transactions.csv (
    set datestr=%date:~10,4%%date:~7,2%%date:~4,2%%time:~0,2%%time:~3,2%%time:~6,2%
    rename Transactions.csv Transactions-%datestr%.csv
    curl -s -o curl.log --form upload=@Transactions-%datestr%.csv http://192.168.5.217/test_upload.php
    set datestr=
)

Файл переименовывается в «Transactions-.csv», и команда curl работает нормально, поскольку отправляет файл как есть, но я бы хотел, чтобы файл переименовывался правильно.

Если я закомментирую эхо в автономном режиме, то получу ответ:

if exist Transactions.csv (
    set datestr=20112206112720
    rename Transactions.csv Transactions-.csv
    curl -s -o curl.log --form upload=@Transactions-.csv http://192.168.5.217/test_upload.php
    set datestr=
)

Обратите внимание на отсутствующие области, где должен быть% datestr%.

Есть идеи, почему эти переменные не анализируются должным образом?

Ответы [ 4 ]

3 голосов
/ 23 июня 2011

Если у вас есть блок команд, заключенный в скобки, весь блок анализируется перед выполнением его первой команды. Это означает, что все выражения %var% внутри этого блока заменяются их значениями в то время . Вот почему вы не могли видеть ничего вместо %datestr%, когда запускали скрипт с @echo off закомментированным.

Таким образом, ваше решение переместить тело оператора IF за скобки было правильным.

Другим решением этой проблемы будет использование отложенного расширения:

@echo off

setlocal EnableDelayedExpansion

if exist Transactions.csv (
    set datestr=!date:~10,4!!date:~7,2!!date:~4,2!!time:~0,2!!time:~3,2!time:~6,2!
    rename Transactions.csv Transactions-!datestr!.csv
    curl -s -o curl.log --form upload=@Transactions-!datestr!.csv http://192.168.5.217/test_upload.php
    set datestr=
)

Как видите, режим отложенного расширения вводится командой setlocal EnableDelayedExpansion. Обратите внимание также на изменение синтаксиса: ! вместо % обозначает задержанное расширение соответствующей переменной / выражения. Когда отложенное расширение включено, вы все равно можете использовать % для немедленного расширения, где это необходимо.

2 голосов
/ 23 июня 2011

Обратите внимание, что этот способ анализа даты сильно зависит от используемой локали. %DATE% возвращает текущую дату, используя формат короткой даты, который полностью (бесконечно) настраивается. Один пользователь может настроить свою систему для возврата Fri040811, а другой пользователь может выбрать 08/04/2011 ... это полный кошмар для программиста на BAT.

Есть два решения этой проблемы.

Решение 1, временно измените локаль.

reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f >nul
reg add "HKCU\Control Panel\International" /v sShortDate /d "yyyy-MM-dd" /f >nul
reg add "HKCU\Control Panel\International" /v sTimeFormat /d "HH:mm:ss" /f >nul

выполните вашу логику% DATE%, например

set datestr=%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%
ren test.txt test-%datestr%.txt 

и затем восстановить языковой стандарт обратно

reg copy "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f >nul

Решение 2. использовать WMIC.

WMIC Path Win32_LocalTime Get Day,Hour,Minute,Month,Second,Year /Format:table

возвращает дату удобным способом, чтобы непосредственно проанализировать ее с FOR.

1 голос
/ 22 июня 2011

Я скопировал ваш код в скрипт .cmd и запустил его, и он успешно переименовал файл. Однако вместо того, чтобы вкладывать в скобки, я сделал ссылку на блок GoTo и обернул конкатенацию datestr внутри двойных кавычек. Вот код, который я использовал ...

@echo off
if exist test.txt (
    goto RENFILE
) else (
    goto NOTFOUND
)

:RENFILE
set datestr="%date:~10,4%%date:~7,2%%date:~4,2%%time:~0,2%%time:~3,2%%time:~6,2%"
echo %datestr%
rename test.txt test-%datestr%.txt
goto END

:NOTFOUND
echo file not found!
goto END

:END
pause
1 голос
/ 22 июня 2011

Если я создаю командный файл со следующим содержимым:

@echo off
set datestr=%date:~10,4%%date:~7,2%%date:~4,2%%time:~0,2%%time:~3,2%%time:~6,2%
echo Transactions.csv Transactions-%datestr%.csv
set datestr=

Показывает:

C:\Temp>test
Transactions.csv Transactions-012/133612.csv

Это показывает мне, что на самом деле причиной сбоя является форматирование datestr, которое вы выбрали - значение даты содержит косую черту, которая недопустима в имени файла, и это приводит к сбою rename , (Это должны быть значения, которые вы используете при синтаксическом анализе выходных данных; у вас есть ошибка «один за другим».)

Вы не видите этого в своем жестко запрограммированном тесте, потому что вы жестко закодировали правильно отформатированную дату вместо того, что вы получаете в datestr.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...