Microsoft批处理文件未将参数传递给子例程

时间:2016-06-06 02:54:57

标签: windows batch-file ftp arguments

以下批处理文件未正确地将变量%% a,%% b,%% c正确传递给子例程。

@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,但未正确传递给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

感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

如果ftp_config.txt文件中有看似空的行甚至认为它包含(一个或多个)<tab>(字符列表),我可以重现非常相似的结果。
让我们反对"tokens=1,2,3 delims= "条款:

  • 如果您指定"delims=<space>"Unicode代码点U+0020),for /F(代码点<tab>)的U+0009标记化将失败,反之亦然
  • If you don’t specify delims it will default to "delims=<tab><space>"
  • 因此,您可以指定"tokens=1,2,*"省略delims
  • 不幸的是,还有另一个额外的不可见的类似空格的字符 不间断空格,代码点U+00A0)有效的分隔符。

结论:使用"delims=<tab><No-Break Space><space>";在键盘输入方面(我不知道如何在这里显示它):&#34; delims = Tab Alt + 0160 空间&#34;

即使密码包含% &|<>!,{{ 1}},,;=等(假设计算机和用户名不包含这些内容),请参阅下面的输出:

@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

==>