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

时间:2013-06-10 21:52:11

标签: windows batch-file cmd

所以...嘿伙计们和女孩们。我有一个最奇怪的问题。我写了这个生成文本文件的批处理文件

由于某种原因,我的代码真的搞砸了,你可以看到更好的版本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

它有效!这是故障,我不想只运行这个文件,我想从另一个文件中运行它。

Sooooo在我的另一个.bat我有这一行

@call %0\..\generate_file.bat

再次它工作得很好,调用它,运行它,如果我只有一个条目,那么一切都很好......但如果我输入yes并进入另一个条目它不会创建一个新行它只是继续将新条目附加到旧条目上。如果我只是自己启动generate_file.bat,它可以正常工作。

任何人都有任何想法?

2 个答案:

答案 0 :(得分:1)

伊克!请递给我一大瓶阿司匹林!

Ansgar似乎编辑了原版以匹配pastebin版本 - 如果这是正确的,似乎没有办法可以使用这个例程 - 打电话或不打...

这一行

:no EXIT /B

不起作用。标签行上的任何数据都会被忽略,因此无法EXIT执行此过程。此MUST应写为

:no
EXIT /B

下一个小狡辩是前一行。与PASCAL或DELPHI等语言不同。批处理只是逐行执行,直到达到CALLGOTO EXIT或END-OF-FILE。它在功能或程序意义上没有“块”的概念。标签只是标记。

因此,

GOTO no

是多余的。标题no将在ANSWER yyes之后到达 - GOTO yes周围的括号也是多余的。

下一个小问题是仅按ENTER来响应SET/P不会更改变量的值 - 它将保留set/p之前的任何值。

结果将是answer设置为y,然后回复enter会将answer设置为y - 它将无法清除answer

解决此问题的方法是在执行set/p

之前专门设置值
SET "ANSWER="
SET /P ANSWER=

但是,正如经常发生的那样,这是一条双向的街道。如果您编码

SET "ANSWER=Y"
SET /P ANSWER="[%ANSWER%] "

然后SET/P将提示[Y] - 请注意,此处仅需要引号括起空格。不想要空间?省略引号......

现在这对于name和 - 哦 - 哦 - 另一个陷阱的输入可能更重要。 datetime是您想要的变量的逻辑名称。问题是,它们太合乎逻辑了。他们是magic variables - 最好不要搞砸他们。

任何magic variable都可以在批处理程序中设置,就像普通变量BUT一样,如果它们未设置,系统会将它们设置为 - 好,魔术值。当然是魔术。 %date%包含日期%time%时间 - 还有其他一些日期 - 请参阅提示中的SET /?以获取列表。

魔术变量的问题在于它们不会出现在执行SET的系统初始化变量列表中(没有参数!)更改这些变量不是一个好主意。 。批处理程序通常会假设它们的值。

现在系统初始化变量之一是path - 如果没有显式路径而且它不在当前目录中,那么搜索的目录列表将找到可执行文件。

关于%0\..\建构,最后一点非常重要。 “%0”本身就是批处理文件名。可能是fredfred.batC:\somewhere\somewhereelse\fred.bat - 根据具体情况可能有很多不同的事情。因此%0\..\file.txt可能是不同的东西 - 当前目录中file.txt最有可能。

所以 - 您的原始批次检查当前目录中是否存在file.txt,然后将Erase the file评论到%0\..\file.txt(如果它已经存在) - 可能会转移到.\file.txt(即当前目录中的file.txt - 所以它会覆盖现有文件。

无论如何,例程然后要求三个数据项并使用这个特殊的构造

ECHO |set /p =%name%        %date%       %time%>%0\..\file.txt

它只是简单地响应没有变量,而是提示数据线 定向到文件 - 创建新文件或覆盖(再次)现有文件(单个>表示“在新文件中”)

然后你提示输入另一个条目,这次是附加(>>)到文件。

如果您deleted任何现有文件,然后将appended所有数据都添加到新文件中,那么>>将创建一个文件(如果它尚未创建)会简单得多存在。

所以 - 这是部分修订。我没有删除多余的括号和GOTO,也没有在SET /P之前清除或预设数据值或将提示合并到其中。我甚至留下了变量名。

注意我如何设置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

希望你觉得这很有用!我要休息了。

答案 1 :(得分:0)

替换它:

ECHO |set /p =%name%        %date%        %time%>>%0\..\file.txt

用这个:

>>"%~dp0\file.txt" echo %name%        %date%        %time%

%0是脚本文件本身。使用%~dp0\file.txt代替%0\..\file.txt来访问同一文件夹中的文件。将路径放在双引号之间以避免由于意外空格而产生的意外。并在命令之前放置重定向,以避免像您观察到的那样出现奇怪的输出重定向问题。