简体   繁体   English

从另一个批处理中启动时,批处理文件的行为有所不同

[英]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. 批处理只是简单地逐行执行,直到到达CALLGOTO 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. 除非ANSWERyyes 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. datetime是所需变量的逻辑名称。 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. 它可能是fredfred.batC:\\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.

相关问题 是否可以在程序启动时运行批处理文件? - Is it possible to run a batch file when a program is launched? 应用程序从批处理文件顺序启动 - Applications are launched sequentially from batch file 在另一个批处理中执行批处理文件 - Executing batch file within another batch 从SFX运行时,批处理文件的行为有所不同 - Batch file behaves differently when ran from a SFX 从Windows批处理文件中读取文件并调用另一个.bat - Reading a file and calling another .bat from within a Windows batch file 如何从父批处理文件运行但未调用的另一个批处理文件中查找父批处理文件的名称/路径? - How to find the name/path of a parent batch file from within another batch file RUN, but not CALLed, by the parent? 如何从创建另一个批处理文件的批处理文件中回显尖括号>? - How to ECHO the angle bracket > from within a batch file creating another batch file? 从批处理文件启动时,Visual Studio 2017命令行工具不起作用 - Visual Studio 2017 command line tools don't work when launched from batch file 从Windows服务启动时,批处理文件将不会启动程序 - Batch file won`t start program when launched from windows service 从批处理文件中调用另一个批处理命令会停止进一步执 - calling another batch command from within batch file stops further execution
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM