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
@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. If I just launch generate_file.bat by itself though, it works as intended.
Any one have any ideas?
Eek! 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...
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. This MUST
be written as
:no
EXIT /B
Next little quibble is the previous line. Unlike languages like PASCAL or DELPHI. batch simply executes line after line until it reaches a CALL
, GOTO
EXIT
or 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.
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
.
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
.
The way to overcome this is to specifically set the value before executing the 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. Don't want the space? Omit the quotes...
Now this is probably more important for the entry of name
and - oh-oh - another trap. date
and time
are logical names for the variables you want. Problem is, they're too logical. They're magic variables
- and it's best not to mess with them.
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. By magic, of course. %date%
contains the date, %time%
the time - and there are a bunch of others - see 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. 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.
This last point is significant when it comes to the %0\\..\\
consruct. " %0
" on its own is the batch filename. It may be fred
or fred.bat
or C:\\somewhere\\somewhereelse\\fred.bat
- many different things depending on circumstances. %0\\..\\file.txt
may therefore be different things - file.txt
in the current directory being the most likely.
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.
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.
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. 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...
@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. Use %~dp0\\file.txt
instead of %0\\..\\file.txt
to access a file in the same folder. 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.