2016-06-06 1 views
2

Следующий командный файл неправильно передает переменные %% a, %% b, %% c правильной подпрограмме.Командный файл Microsoft, не передающий аргументы подпрограмме

@echo off 
enter code here`setlocal EnableDelayedExpansion 

FOR /F "tokens=1,2,3 delims= " %%a in (ftp_config.txt) do (
    echo %%a 
    echo %%b 
    echo %%c 
    call :SUB_ftp_cmd %%a %%b %%c 
) 
exit 

:SUB_ftp_cmd 
echo open %1>ftp.txt 
echo %2>>ftp.txt 
echo %3>>ftp.txt 
echo cd /public_html>>ftp.txt 
echo bin>>ftp.txt 
echo hash>>ftp.txt 
echo put "test.txt">>ftp.txt 
echo close>>ftp.txt 
echo bye>>ftp.txt 

c:\windows\system32\ftp.exe -i <ftp.txt 

del ftp.txt 

exit /b 

ftp.config содержит следующее:

domain_name1 username1 password1 
domain_name2 username2 password2 

Содержание ftp.txt заканчивается существо:

open 
ECHO is off. 
ECHO is off. 
cd /public_html 
bin 
hash 
put "test.txt" 
close 
bye 

Я положил несколько строк в качестве отладки и увидеть что %% a, %% b, %% c правильно назначаются в цикле FOR, но не правильно передаются SUB_ftp_cmd.

Обновлен пакетный файл:

@echo off 
setlocal DisableDelayedExpansion 
FOR /F "tokens=1,2,* delims=  " %%a in (ftp_config.txt) do (
    echo(=== for loop variables: a=[%%a], b=[%%b], c=[%%c] 
    set "passw=%%c" 
    call :SUB_ftp_cmd %%a %%b 
) 
exit /B 

:SUB_ftp_cmd 
SETLOCAL EnableDelayedExpansion 
>ftp.txt (
echo open %1 
echo(%2 
echo(!passw! 
echo cd /public_html 
echo bin 
echo hash 
echo put "test.txt" 
echo close 
echo bye 
) 
ENDLOCAL 
echo(=== ftp.txt content 
type ftp.txt 
echo(=== ftp command is merely displayed using `ECHO` 
ECHO c:\windows\system32\ftp.exe -i -s:ftp.txt 
echo(
rem del ftp.txt 
exit /b 

ftp_config.txt имеет:

"ftp.domain1.com" username1 pas3&^#%$ 
"ftp.domain2.com" username2 passworks 

в результате ftp.txt:

open "ftp.domain2.com" 
username2 

cd /public_html 
bin 
hash 
put "test.txt" 
close 
bye 

Любая помощь приветствуется.

+0

'FTP /' говорит, что нужно использовать 'FTP -i -s: ftp.txt' вместо 'ftp.exe -i > ftp.txt' – JosefZ

ответ

3

я могу воспроизвести очень похожие результаты, если есть , казалось бы, пустая строка в файле ftp_config.txt даже подумал, что содержит (один или более) <tab> (Character) табуляции.
Давайте спорить против "tokens=1,2,3 delims= " пункта:

  • Если указать "delims=<space>" (UnicodeU+0020) элемент кода, то for /F лексического анализа подведет для <tab> (элемент кода U+0009) и наоборот.
  • If you don’t specify delims it will default to "delims=<tab><space>".
  • Следовательно, вы можете указать "tokens=1,2,*", опуская delims.
  • К сожалению, есть еще один дополнительный невидимый пространственноподобен характер   (Нет-Break Space, не U+00A0 элемент кода), который не является допустимым разделителем.

Вывод: использовать "delims=<tab><No-Break Space><space>"; в терминах ввода с клавиатуры (я не знаю, как лучше показать его здесь): «delims = TabAlt + 0160Пробел".

Следующий скрипт должен работать, даже если пароль содержит cmd poisonous characters or valid delimiters как %, &, |, <, >, !, ,, ;, = и т.д.(Предполагая, что компьютер и пользовательские имена не содержат те из них), см выход ниже:

@echo off 
setlocal DisableDelayedExpansion 
rem FOR /F "tokens=1,2,*" %%a in (ftp_config.txt) do (
rem in next line  delims=<tab><No-Break Space><space>" %%a … 
FOR /F "tokens=1,2,* delims=   " %%a in (ftp_config.txt) do (
    echo(=== for loop variables: a=[%%a], b=[%%b], c=[%%c] 
    set "passw=%%c" 
    call :SUB_ftp_cmd %%a %%b 
) 
exit /B 

:SUB_ftp_cmd 
SETLOCAL EnableDelayedExpansion 
>ftp.txt (
echo open %1 
echo(%2 
echo(!passw! 
echo cd /public_html 
echo bin 
echo hash 
echo put "test.txt" 
echo close 
echo bye 
) 
ENDLOCAL 
echo(=== ftp.txt content 
type ftp.txt 
echo(=== ftp command is merely displayed using `ECHO` 
ECHO c:\windows\system32\ftp.exe -i -s:ftp.txt 
echo(
del ftp.txt 
exit /b 

Выход:

==> D:\bat\SO\37648941.bat 
=== for loop variables: a=[domain_name1], b=[username1], c=[pass&,!%word1] 
=== ftp.txt content 
open domain_name1 
username1 
pass&,!%word1 
cd /public_html 
bin 
hash 
put "test.txt" 
close 
bye 
=== ftp command is merely displayed using `ECHO` 
c:\windows\system32\ftp.exe -i -s:ftp.txt 

=== for loop variables: a=[domain_name2], b=[username2], c=[pass<;!%word2] 
=== ftp.txt content 
open domain_name2 
username2 
pass<;!%word2 
cd /public_html 
bin 
hash 
put "test.txt" 
close 
bye 
=== ftp command is merely displayed using `ECHO` 
c:\windows\system32\ftp.exe -i -s:ftp.txt 

==> 
+0

Спасибо JosefZ, это решило передать имя_домена и имя пользователя, однако я все равно получаю «ECHO выключен». для строки, которая должна содержать пароль. Файл ftp_config.txt не содержит пробелов. В пароле содержатся специальные символы [! |^| и т. д.], любые другие требования, которые мне нужно правильно обрабатывать пароль? – ruaok

+0

@ruaok См. Мой обновленный ответ, обратите внимание на левую скобку как в «echo (% 2», так и 'echo (! Passw!'). Это должно привести к пустой строке вывода, подавляющей сообщение «ECHO is off» в случае '% 2 'или'! passw! 'пуст. Пожалуйста, [отредактируйте свой вопрос] (http://stackoverflow.com/posts/37648941/edit) и добавьте [mcve] вашего' ftp_config.txt' и соответствующего вывода, как я делаю в мой ответ – JosefZ

+0

Привет, JosefZ, я ценю ваше подробное внимание. Я обновил вопросы с внесенными вами изменениями и все еще вижу проблему с паролем. Добавление левой скобки в обоих эхах (% 2 и echo (! passw) ! изменил результат на пустую строку для пароля в ftp.txt – ruaok