Тема: CMD/BAT: Работа с переменными
Здравствуйте, столкнулся с такой проблемой:
как мне сделать чтобы значение переменой бралось из .txt файла, допустим такая ситуация
нужно подключится к FTP, из файла(1.txt) берётся пароль а из (2.txt) логин
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Здравствуйте, столкнулся с такой проблемой:
как мне сделать чтобы значение переменой бралось из .txt файла, допустим такая ситуация
нужно подключится к FTP, из файла(1.txt) берётся пароль а из (2.txt) логин
Чем планируете подключаться к ftp?
А вообще значение из файла в переменную прочитать проще всего, например, так:
@echo off
setlocal
set sFile=0001.txt
if exist "%sFile%" <"%sFile%" set /p sUser=>nul
if defined sUser echo %sUser%
endlocal
exit /b 0
Чем планируете подключаться к ftp?
Программой curl.exe
set sFTP=сервер
set sUser=логин
set sPass=пароль
Хм.. не работает, сделал так(чтобы проверить)
@echo off
setlocal
set sFile=0001.txt
if exist "%sFile%" <"%sFile%" set /p sUser=>nul
if defined sUser echo %sUser%
echo.%sFile%>>YRA.txt
endlocal
exit /b 0
в итоге создаётся txt файл а там просто "0001.txt"
А вот сам разобрался:
set T=type C:\1.txt
А как мне создать файл таким образом:
set T=type C:\1.txt //создаётся переменная %T% а её значение берётся из файла C:\1.txt
Нужно создать txt файл с "таким" именем %Т%.txt
Хм.. не работает, сделал так(чтобы проверить)…в итоге создаётся txt файл а там просто "0001.txt"
Естественно:
echo.%sFile%>>YRA.txt
Так и должно быть. А Вы что ожидали?
А вот сам разобрался…
Не разобрались.
Ещё раз.
Переменной окружения «sFile» присваивается имя файла «0001.txt» (дабы не повторять его несколько раз в коде):
set sFile=0001.txt
Если существует файл, заданный переменной окружения «sFile»…
if exist "%sFile%"…
…то производится чтение этого файла (<"%sFile%") и содержимое первой строки передаётся в переменную окружения «sUser» (set /p sUser=); вывод самой команды «set /p» подавляется (>nul):
…<"%sFile%" set /p sUser=>nul
Далее. Если была определена переменная окружения «sUser» (if defined sUser), то производится демонстрация её содержимого (echo %sUser%):
if defined sUser echo %sUser%
alexii, поспешил я, сейчас точно во всём разобрался, спасибо что объяснил)
Если будут вопросы — пишите, ничего страшного.
А как сделать так чтобы, содержимое первой строки передавалось переменной %sUser% а вторая строка в %sLogin%
Командой «set /p», без извращений — никак, поскольку она не воспринимает передачу по конвейеру. Извратиться можно, например, так:
0001.txt
User Name
My password
@echo off
setlocal
set sFile=0001.txt
set sTempFile=TempFile.tmp
if exist "%sFile%" (
<"%sFile%" set /p sUser=>nul
more +1 "%sFile%">"%sTempFile%"
<"%sTempFile%" set /p sPass=>nul
del "%sTempFile%"
)
if defined sUser echo %sUser%
if defined sPass echo %sPass%
endlocal
exit /b 0
Можно делать разбор, по приведённому примеру — тоже не слишком красивый, например так:
@echo off
setlocal
set sFile=0001.txt
if exist "%sFile%" (
for /f "usebackq delims=" %%i in ("%sFile%") do set sUser=%%i& goto :Skip
:Skip
for /f "usebackq skip=1 delims=" %%i in ("%sFile%") do set sPass=%%i
)
if defined sUser echo %sUser%
if defined sPass echo %sPass%
endlocal
exit /b 0
Тут уж лучше сделать текстовый файл a-la *.ini, наподобие:
0001.txt
; My user name & password
user=User Name
password=My password
и пакетный файл к нему:
@echo off
setlocal
set sFile=0001.txt
if exist "%sFile%" (
for /f "usebackq tokens=1,2 eol=; delims==" %%i in ("%sFile%") do set %%i=%%j
)
if defined User echo %User%
if defined Password echo %Password%
endlocal
exit /b 0
А как сделать так чтобы, содержимое первой строки передавалось переменной %sUser% а вторая строка в %sLogin%
Командой «set /p», без извращений — никак, поскольку она не воспринимает передачу по конвейеру.
Разве это
if exist "%sFile%" <"%sFile%" (
set /p sUser=
set /p sPass=
)
не работает?!
Насколько я могу судить, при перенапралении на вход файла, SET /P всё-таки позволяет читать последовательно строки. Другое дело, что при неизвестном числе строк не удасться узнать, достигнут ли конец файла. (Также трудности с чтением файла с помощью SET /P у меня возникали при переключении кодировок.)
Другое дело — перенаправление на вход SET /P вывода другой программы или команды. В этом случае возникают две трудности (наряду с тем, что нельзя определить, достигнут ли конец потока):
1) команда SET /P или содержащие ее составная команда или командный файл запускаются в новом процессе CMD.EXE с ключом /C, по отрабатыванию которого прочитанные строки теряются; но это еще не беда, главное — об этом помнить;
2) при достижении команды SET /P из всех успевших поступить на вход строк считывается самая первая — остальные теряются. Таким образом, гарантированно будет получена только первая строка из потока; может быть, удасться поймать невпопад ещё несколько, если только между выводами строк нет достаточной временной задержки.
И, кстати, «if exist "%sFile%"» можно не проверять,
можно просто подавить сообщение об ошибке:
((
set /p sUser=
set /p sPass=
)<0001.txt) 2>nul
Разве это
if exist "%sFile%" <"%sFile%" ( set /p sUser= set /p sPass= )
не работает?!
Это как раз работает. Очевидно, дело в том, что в данном случае ввод осуществляется как групповая операция. Мне почему-то ранее не приходило в голову испробовать такой подход. Будем знать.
И, кстати, «if exist "%sFile%"» можно не проверять, можно просто подавить сообщение об ошибке:
Подавить-то можно. Но не следует (я просто не расписывал ветвь Else с сообщением об ошибке).
(я просто не расписывал ветвь Else с сообщением об ошибке)
Кроме несуществования файла, возможны и другие ошибки при попытке доступа к нему, к тому же он может быть удалён другой программой сразу же после проверки его существования.
Поэтому, может быть, лучше проверять наличие ошибки после попытки выполнить действие:
((try)<file.txt) 2>nul
if errorlevel 1 (catch)
или
((try)<file.txt) 2>nul || (catch)
— второй способ мне представляется предпочтительнее, т.к. им обрабываются ошибки, при которых errorlevel равен 0.
В качестве примера такой ошибки (других я, правда, и не знаю) могу назвать попытку повторно открыть для записи файл.
Вот как её можно воспроизвести:
запускаем командную строку в двух окнах с одинаковым рабочим каталогом,
в одном выполняем команду
(pause>con)>tmp.txt
и не выходим из паузы,
пытаемся во втором окне выполнить
(echo 123)>tmp.txt
и получаем в ответ:
Процесс не может получить доступ к файлу, так как этот файл занят другим процессом.
errorlevel при этом будет равен 0, так что по нему о существовании ошибки узнать нельзя.
Тем не менее второй подход
((echo 123)>tmp.txt) 2>nul || echo Ошибка!
ошибку видит.
Как Вы определяли, что errorlevel был равен нулю?
echo %errorlevel%
В качестве примера такой ошибки (других я, правда, и не знаю) могу назвать попытку повторно открыть для записи файл.
Сейчас проверил для SET /P из несуществуещего файла — тоже 0, хотя, кажется, раньше был 1, может я что-то путаю или неправильно делаю.
Я имел в виду — для приведённого выше кода:
((echo 123)>tmp.txt) 2>nul || echo Ошибка!
А я имел в виду для кода
(echo 123)>tmp.txt
очевидно, во втором случае, до момента «echo Ошибка!» всё то же самое, к тому же errorlevel представляет интерес именно в первом случае, во втором наличие ошибки обнаруживается и без него
(впрочем, скобки вокруг echo 123 в обоих случаях лишние, но без них всё то же самое).
alexii - Вы правы - верный пример, работающим с gpg (ранее может и писал или не писал)
+ и страждущим стдоут в скобках не всегда тот же, что за скобками
+ и страждущим стдоут в скобках не всегда тот же, что за скобками
Согласен, и stderr тоже. Впрчем, это (для stdout) уже видно из
(pause>con)>tmp.txt
в примере со stderr скобки тоже стоят на своих местах, если убрать лишние останется
(echo 123>tmp.txt) 2>nul || echo Ошибка!
так что не ясно, о чём замечание.
alexii - Вы правы - верный пример, работающим с gpg (ранее может и писал или не писал)
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться