[英]batch file acts differently when launched from within another batch
So... hey guys and gals. 所以...嘿,伙计们 I have the weirdest problem.
我有最奇怪的问题。 I wrote this batch file which generate a text file
我写了这个批处理文件,生成了一个文本文件
My code which for some reason gets really messed up is bellow, you can see a better version here 我的代码,因为某些原因变得非常搞砸是波纹管,你可以看到一个更好的版本在这里
@ECHO OFF
IF NOT EXIST file.txt goto generate
ECHO Erase the file>%0\..\file.txt
:generate
ECHO.
ECHO.
ECHO generating Table file for you
ECHO Please enter a name:
SET /P name=
ECHO.
ECHO Please enter the date:
SET /P date=
ECHO.
ECHO Please enter the time:
SET /P time=
ECHO.
ECHO.
ECHO Huzzah!
ECHO |set /p =%name% %date% %time%>%0\..\file.txt
:repeat
ECHO Do you want to add another entry? (Y/N)
SET /P answer=
IF /i {%ANSWER%}=={y} (GOTO yes)
IF /i {%ANSWER%}=={yes} (GOTO yes)
GOTO no
:no EXIT /B
:yes
ECHO.
ECHO.
ECHO Please enter a name:
SET /P name=
ECHO.
ECHO Please enter the date:
SET /P date=
ECHO.
ECHO Please enter the time:
SET /P time=
ECHO.
ECHO.
ECHO Huzzah!
ECHO.>>file.txt
ECHO |set /p =%name% %date% %time%>>%0\..\file.txt
GOTO repeat
And it works! 而且有效! Here is the glitch, I don't want to just run this file, I want to run this from within another file.
这是故障,我不想只运行此文件,我想从另一个文件中运行它。
Sooooo in my other .bat I have this line Sooooo在我的另一个.bat中,我有这条线
@call %0\..\generate_file.bat
Again it works great, calls it up, runs it, and if I only have one entry then everything is fine... however if I enter yes and go to enter another entry it doesn't create a new line it just keeps appending the new entries onto the old ones. 再次它很好用,调用它,运行它,如果我只有一个条目,那么一切都很好...但是,如果我输入yes并进入另一个条目,它不会创建新行,它只会继续附加新条目到旧条目上。 If I just launch generate_file.bat by itself though, it works as intended.
如果我只是自己启动generate_file.bat,它将按预期工作。
Any one have any ideas? 有人有想法么?
Eek! ek! Please hand me my LARGE bottle of aspirin!
请把我的大瓶阿司匹林交给我!
Ansgar seems to have edited the original to match the pastebin version - and if that's correct, there appears to be no way in which this routine could work - call or no... Ansgar似乎已对原始文件进行了编辑,以匹配pastebin版本-如果是正确的话,则该例程似乎无法工作-调用还是不执行...
This line 这条线
:no EXIT /B
won't work. 将无法正常工作。 Any data on a label-line is ignored, so there's no way of
EXIT
ing the procedure. 标签行上的所有数据都将被忽略,因此无法
EXIT
该过程。 This MUST
be written as 这
MUST
写成
:no
EXIT /B
Next little quibble is the previous line. 下一个小问题是上一行。 Unlike languages like PASCAL or DELPHI.
与PASCAL或DELPHI等语言不同。 batch simply executes line after line until it reaches a
CALL
, GOTO
EXIT
or END-OF-FILE. 批处理只是简单地逐行执行,直到到达
CALL
, GOTO
EXIT
或END-OF-FILE为止。 It has no concept whatever of "blocks" in the sense of functions or procedures. 从功能或过程的意义上讲,它没有任何“块”的概念。 Labels are just markers.
标签只是标记。
Hence, the 因此,
GOTO no
is superfluous. 是多余的。 The label
no
will be reached UNLESS ANSWER
is y
or yes
- and the parentheses around the GOTO yes
are also redundant. 除非
ANSWER
是y
或yes
no
将到达标签no-并且GOTO yes
周围的括号也是多余的。
The next little problem is that pressing just ENTER
in response to a SET/P
will not change the variable's value - it will retain any value it had before the set/p
. 下一个小问题是响应
SET/P
仅按ENTER
不会更改变量的值-它将保留set/p
之前的任何值。
The consequence will be that should answer
be set to y
, then responding enter
will leave answer
set to y
- it won't clear answer
. 结果是应该将
answer
设置为y
,然后响应enter
将使answer
设置为y
它不会清除answer
。
The way to overcome this is to specifically set the value before executing the set/p
解决此问题的方法是在执行
set/p
之前专门设置值
SET "ANSWER="
SET /P ANSWER=
But, as often happens, this is a two-way street. 但是,这经常是两条路。 If you code
如果您编码
SET "ANSWER=Y"
SET /P ANSWER="[%ANSWER%] "
Then the SET/P
will prompt with [Y]
- note that the quotes are only required here to enclose the space. 然后
SET/P
将以[Y]
提示-注意,此处仅需使用引号将空格括起来。 Don't want the space? 不需要空间吗? Omit the quotes...
省略引号...
Now this is probably more important for the entry of name
and - oh-oh - another trap. 现在,这对于输入
name
和-哦-哦-另一个陷阱可能更为重要。 date
and time
are logical names for the variables you want. date
和time
是所需变量的逻辑名称。 Problem is, they're too logical. 问题是,它们太合逻辑了。 They're
magic variables
- and it's best not to mess with them. 它们是
magic variables
-最好不要弄乱它们。
Any magic variable
may be set in a batch program just the same as an ordinary variable BUT if they are left un-set, the system sets them to - well, magic values. 如果未设置任何
magic variable
则可以在批处理程序中将其设置为与普通变量BUT相同的设置,系统会将它们设置为-魔术值。 By magic, of course. 当然是靠魔术。
%date%
contains the date, %time%
the time - and there are a bunch of others - see SET /?
%date%
包含日期, %time%
包含时间-还有很多其他内容-请参阅SET /?
from the prompt for a list. 从提示列表中。
The problem with the magic variables is that they don't appear in the list of system-initialised variables you'd get from executing SET
(without parameters!) It's not a good idea to change these, either. 魔术变量的问题在于,它们不会出现在通过执行
SET
(没有参数!)而获得的系统初始化变量的列表中。更改这些变量也不是一个好主意。 Batch programs will usually assume their values. 批处理程序通常将采用其值。
Now one of the system-initialised variables is path
- the list of directories that get searched to find an execuable if no explicit path is made and it's not in the current directory. 目前,该系统初始化的变量之一是
path
-即获得搜索以找到一个execuable如果没有明确的路径是由目录的列表,它不是在当前目录中。
This last point is significant when it comes to the %0\\..\\
consruct. 关于
%0\\..\\
构造,最后一点很重要。 " %0
" on its own is the batch filename. “
%0
”本身就是批处理文件名。 It may be fred
or fred.bat
or C:\\somewhere\\somewhereelse\\fred.bat
- many different things depending on circumstances. 它可能是
fred
或fred.bat
或C:\\somewhere\\somewhereelse\\fred.bat
根据情况有很多不同的东西。 %0\\..\\file.txt
may therefore be different things - file.txt
in the current directory being the most likely. %0\\..\\file.txt
可能有所不同-当前目录中的file.txt
最有可能。
So - your original batch checks to see whether file.txt
exists in the current directory, then comments Erase the file
into %0\\..\\file.txt
if it does already exist - probably into .\\file.txt
(ie file.txt
in the current directory) - so it overwrites the existing file. 因此-您的原始批处理将检查
file.txt
是否在当前目录中存在,然后注释Erase the file
到%0\\..\\file.txt
如果Erase the file
已经存在)-可能会写入.\\file.txt
(即file.txt
当前目录中的file.txt
)-因此它会覆盖现有文件。
Regardless, the routine then asks for the three data items and uses this peculiar construct 无论如何,例程随后会询问三个数据项并使用此特殊的构造
ECHO |set /p =%name% %date% %time%>%0\..\file.txt
Which simply responds nothing into no variable, but prompting with the data line which gets directed to the file - creating a new file or overwriting (again) an existing one (a single >
means "in a new file") 它只是对变量没有任何反应,而只是对指向该文件的数据行进行提示-创建新文件或覆盖(再次)现有文件(单个
>
表示“在新文件中”)
Then you prompt for another entry, this time APPENDING ( >>
) to the file. 然后,提示您输入另一个条目,这次是在文件中追加(
>>
)。
It would be far simpler if you deleted
any existing file, then appended
all of your datalines to a new file - a >>
will create a file if it doesn't already exist. 如果
deleted
任何现有文件,然后appended
所有数据行appended
到一个新文件,这将更加简单- >>
将创建一个文件(如果尚不存在)。
So - here's a partial revision. 所以-这是部分修订。 I've not removed superfluous parentheses and
GOTO
s, nor have I cleared or preset data values prior to SET /P
s or incorporated prompts into them. 我没有删除多余的括号和
GOTO
,也没有在SET /P
之前清除或预设数据值或将提示并入其中。 I've even left the variable names. 我什至没有留下变量名。
Note how I've set filename
- gets set once, so that the variable %filename%
can be used for the file rather than constantly repeating the same string - painful if you decide to change the filename... 请注意我如何设置
filename
-设置一次,以便变量%filename%
可用于文件而不是不断重复相同的字符串-如果您决定更改文件名会很麻烦...
@ECHO OFF
SET filename=%~dp0%file.txt
ECHO %filename%
IF NOT EXIST %filename% goto generate
ECHO Erase the file %filename%
DEL %filename%
:generate
ECHO.
ECHO.
ECHO generating Table file for you
:yes
ECHO Please enter a name:
SET /P name=
ECHO.
ECHO Please enter the date:
SET /P date=
ECHO.
ECHO Please enter the time:
SET /P time=
ECHO.
ECHO.
ECHO Huzzah!
ECHO(%name% %date% %time%>>%filename%
:repeat
ECHO Do you want to add another entry? (Y/N)
SET /P answer=
IF /i {%ANSWER%}=={y} (GOTO yes)
IF /i {%ANSWER%}=={yes} (GOTO yes)
GOTO no
:no
EXIT /B
Hope you find this useful! 希望你觉得这个有用! I'm off for a lie-down.
我要躺下。
Replace this: 替换为:
ECHO |set /p =%name% %date% %time%>>%0\..\file.txt
with this: 有了这个:
>>"%~dp0\file.txt" echo %name% %date% %time%
%0
is the script file itself. %0
是脚本文件本身。 Use %~dp0\\file.txt
instead of %0\\..\\file.txt
to access a file in the same folder. 使用
%~dp0\\file.txt
代替%0\\..\\file.txt
来访问同一文件夹中的文件。 Put the path between double quotes to avoid surprises due to unexpected spaces. 在双引号之间放置路径,以免由于意外的空格而引起意外。 And put the redirection before the command to avoid weird output redirection issues like the one you observed.
并将重定向放在命令之前,以避免像您观察到的那样奇怪的输出重定向问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.