下列批处理文件没有正确地将变量%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
我在debug中放了几行代码,看到for循环中正确地分配了%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
如有任何帮助,我们将不胜感激。
最佳答案
如果在ftp_config.txt
文件中有一个看似空的行,即使它包含(一个或多个)<tab>
(字符列表),我也能复制非常相似的结果。让我们反对"tokens=1,2,3 delims= "
条款:
如果指定"delims=<space>"
(UnicodecodepointU+0020
),则for /F
的标记化将失败(codepoint<tab>
),反之亦然。
If you don’t specify U+0009
it will default to delims
因此,您可以指定完全忽略"delims=<tab><space>"
。
不幸的是,还有另一个额外的不可见空格,如character"tokens=1,2,*"
(没有中断空格,codepointdelims
)不是有效的分隔符。
结论:使用
;在键盘输入方面(我不知道如何更好地在这里显示):“delims=tabalt+0160space”。
即使密码包含U+00A0
poisonous characters or valid delimiters,如"delims=<tab><No-Break Space><space>"
,cmd
,%
,&
,|
,<
,>
,!
,,
,;
,=
,等(假设计算机和用户名不包含这些密码),下一个脚本也应该可以工作,请参见下面的输出:
@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
==>