I turned off echo in bat file.
#echo off
then I do something like this
...
echo %INSTALL_PATH%
if exist %INSTALL_PATH%(
echo 222
...
)
and I get:
The system cannot find the path specified.
message between those two echos.
What can be the reason of this message and why message ignores echo off?
As Mike Nakis said, echo off only prevents the printing of commands, not results. To hide the result of a command add >nul to the end of the line, and to hide errors add 2>nul. For example:
Del /Q *.tmp >nul 2>nul
Like Krister Andersson said, the reason you get an error is your variable is expanding with spaces:
set INSTALL_PATH=C:\My App\Installer
if exist %INSTALL_PATH% (
Becomes:
if exist C:\My App\Installer (
Which means:
If "C:\My" exists, run "App\Installer" with "(" as the command line argument.
You see the error because you have no folder named "App". Put quotes around the path to prevent this splitting.
Save this as *.bat file and see differences
:: print echo command and its output
echo 1
:: does not print echo command just its output
#echo 2
:: print dir command but not its output
dir > null
:: does not print dir command nor its output
#dir c:\ > null
:: does not print echo (and all other commands) but print its output
#echo off
echo 3
#echo on
REM this comment will appear in console if 'echo off' was not set
#set /p pressedKey=Press any key to exit
"echo off" is not ignored. "echo off" means that you do not want the commands echoed, it does not say anything about the errors produced by the commands.
The lines you showed us look okay, so the problem is probably not there. So, please show us more lines. Also, please show us the exact value of INSTALL_PATH.
#echo off
// quote the path or else it won't work if there are spaces in the path
SET INSTALL_PATH="c:\\etc etc\\test";
if exist %INSTALL_PATH% (
//
echo 222;
)
For me this issue was caused by the file encoding format being wrong.
I used another editor and it was saved as UTF-8-BOM so the very first line I had was #echo off but there was a hidden character in the front of it.
So I changed the encoding to plain old ANSI text, and then the issue went away.
Related
I have had plenty of problems when moving lines inside IF/ELSE structure. Code below does not print
echo %VALUE1%;%VALUE2:~0,2%;%VALUE3%;%VALUE4%;%VALUE5%
to file. Instead of that values are printed to console and last character is dropped. What is the problem?
#echo off
setlocal enabledelayedexpansion
SET ENABLED_X=1
SET FILE=test.txt
SET VALUE1=23,5
SET VALUE2=34,1
SET VALUE3=0,45
SET VALUE4=3,33
SET VALUE5=3,5
IF /I %ENABLED_X%==0 (
echo %VALUE1%;%VALUE2%;%VALUE3%;%VALUE4%>>%FILE%
echo NOT ENABLED
) ELSE (
echo %VALUE1%;%VALUE2:~0,2%;%VALUE3%;%VALUE4%;%VALUE5%>>%FILE%
echo %VALUE1%;%VALUE2:~0,2%;%VALUE3%;%VALUE4%;%VALUE5%
echo ENABLED
)
The part 5>>test.txt will be interpreted as redirection. Normally it's used as 1>>file or 2>>file to redirect standard output and error output, respectively.
Use
>>%FILE% echo %VALUE1%;%VALUE2:~0,2%;%VALUE3%;%VALUE4%;%VALUE5%
instead. Doing the redirection at the beginning of the line will never let it interfere with something else.
Note: without quotes, %FILE% is ok. You might run into trouble when using spaces in the file name.
Just place a single space before both of your >>
or
(echo %VALUE…)>>%FILE%
i was toying around with cmd a bit and wanted to write a little application which involves a simple feature to read a counter from a txt file, then work with it and at the end raise the counter by one.
set /p x=<file.txt
...
set /a y=x+1
echo %y%>file.txt
Problem is it always returns "ECHO ist eingeschaltet (ON)." which translates to ECHO is turned on (ON) for some reason. Could somebody please explain where it comes from and how to fix it? I dont need anything fancy. I just want it to work and know where my mistake is.
At first, I want to show you how your echo command line should look like:
> "file.txt" echo(%y%
Here is your original line of code again:
echo %y%>file.txt
The reason for the unexpected output ECHO is on./ECHO is off. is because the echo command does not receive anything to echo (type echo /? and read the help text to learn what on/off means). Supposing y carries the value 2, the line expands to:
echo 2>file.txt
The number 2 here is not taken to be echoed here, it is consumed by the redirection instead; according to the article Redirection, 2> constitutes a redirection operator, telling to redirect the stream with the handle 2 (STDERR) to the given file. Such a handle can reach from 0 to 9.
There are some options to overcome that problem:
inserting a SPACE in between the echoed text and the redirection operator:
echo %y% >file.txt
the disadvantage is that the SPACE becomes part of the echoed text;
placing parentheses around the echo command:
(echo %y%)>file.txt
placing the redirection part at the beginning of the command line:
>file.txt echo %y%
I prefer the last option as this is the most general and secure solution. In addition, there is still room for improvement:
quote the file path/name to avoid trouble in case it contains white-spaces or other special characters;
use the odd syntax echo( to be able to output everything, even an empty string or literal strings like on, off and /?;
> "file.txt" echo(%y%
Hint:
To see what is actually going on, do not run a batch file by double-clicking on its icon; open a command prompt window and type its (quoted) path, so the window will remain open, showing any command echoes and error messages. In addition, for debugging a batch file, do not put #echo off on top (or comment it out by preceding rem, or use #echo on) in order to see command echoes.
Echo on means that everything that is executed in the batch is also shown in the console. So you see the command and on the following line the result.
You can turn this off with the echo off command or by preceding a # sign before the command you want to hide.
so
::turns of the echo for the remainder of the batch or untill put back on
::the command itself is not shwn because off the #
#echo off
set /p x=<file.txt
...
::the following won't be shown regardless the setting of echo
#set /a y = x+1
echo %y% > file.txt
EDIT after first comment
because your command echo %y%>file.txt doesn't work, you need a space before the > symbol, now you get the result of echo which gives you the current setting of echo
here a working sample, I put everything in one variable for sake of simplicity.
echo off
set /p x =< file.txt
set /a x += 1
echo %x% > file.txt
I wrote the following:
#ECHO OFF
SET v1old=4
SET v2old=0
SET v3old=7453
SET v1new=83
SET v2new=645
SET v3new=2
SET bug=SET
ECHO #ECHO OFF ^& SETLOCAL>>newupdate.bat
ECHO REM .>>newupdate.bat
ECHO REM version von dolphin>>newupdate.bat
ECHO %bug% v1old=%v1new%>>newupdate.bat
ECHO %bug% v2old=%v2new%>>newupdate.bat
ECHO %bug% v3old=%v3new%>>newupdate.bat
ECHO %bug% bug=%bug%
PAUSE
EXIT
The following line will be shown in console instead of beeing written into the bat file:
ECHO %bug% v3old=%v3new%>>newupdate.bat
The variable v3new stores a value from 0-9 if I let them store something other like chars, signs or values with more then 1 digit it will work...
I want that the script mutates himself where only the first lines will change.
So I want to write the first lines to a new file...
Why does it not work, is that a bug or do I do something wrong?
Solutions
The answer by Seth McCauley works fine for the echo-ed set lines.
An alternative and more generic solution is to put every echo within parentheses like this, hence the original set string is redirected without any modification:
(ECHO %bug% v3old=%v3new%)>>newupdate.bat
Another yet worse possibility is to insert a single SPACE before redirection >/>>; this prevents the line from being displayed in the console window, but the SPACE is redirected as well (and, when newupdate.bat is executed, it will be assigned to the variable value as well).
Root Cause
The problem is the combination of characters that appear in the failing echo line (the third one here):
ECHO %bug% v1old=%v1new%>>newupdate.bat
ECHO %bug% v2old=%v2new%>>newupdate.bat
ECHO %bug% v3old=%v3new%>>newupdate.bat
Remove #echo off from the top of your batch script temporarily and you will see what command line is echoed to the console respectively:
ECHO SET v1old=83 1>>newupdate.bat
ECHO SET v2old=645 1>>newupdate.bat
ECHO SET v3old= 2>>newupdate.bat
The console shows the unwanted response, which is not written to newupdate.bat unintentionally:
SET v3old=
This is because of the character substring =2>> in the expanded and echoed command. Why:
= acts as a separator, like also SPACE, ,, ;.
Because of the preceding separator =, 2>> is treated as the redirection operator.
2, since it is a one-digit number immediately preceding >>, is taken as a handle for redirection, where 2 means STDERR (1 is STDOUT, the default for >/>>; 0 is STRIN, 3 - 9 are undefined).
All this means that STDERR is redirected into newupdate.bat rather than the echo-ed line which appears at STDOUT (handle 1). STDERR carries no data here so nothing goes to the file.
For the other lines, as at least one of the above listed conditions is violated, redirection is not modified unintentionally, so >> (same as 1>>) is applied, so STDOUT is redirected into the file and STDERR goes to the console but is empty anyway.
So STDOUT carries the following data with respect to the above three lines:
SET v1old=83
SET v2old=645
Note that without redirection, both STDOUT and STDERR were passed to the console as per default.
Reference this resource for the redirection syntax and this post for a great explanation of redirection.
Conclusion
Since there is a separator (one of SPACE, ,, ;, =) followed by a variable string portion followed by redirection signs >>, it could happen that unintended redirections occur, when the said central string becomes a single decimal figure.
All of the solutions presented on top of this answer (including the referenced one) work because there is a character inserted in between the redirection mark >> and the preceding string portion.
Here are two modern methods to echo into a file without trailing spaces:
Note the first redirection only has one > to create or overwrite the file.
#ECHO OFF
SET v1old=4
SET v2old=0
SET v3old=7453
SET v1new=83
SET v2new=645
SET v3new=2
SET bug=SET
>newupdate.bat ECHO #ECHO OFF ^& SETLOCAL
>>newupdate.bat ECHO REM .
>>newupdate.bat ECHO REM version von dolphin
>>newupdate.bat ECHO %bug% v1old=%v1new%
>>newupdate.bat ECHO %bug% v2old=%v2new%
>>newupdate.bat ECHO %bug% v3old=%v3new%
ECHO %bug% bug=%bug%
PAUSE
EXIT
This method is very useful, but ) need to be escaped to ^) also
#ECHO OFF
SET v1old=4
SET v2old=0
SET v3old=7453
SET v1new=83
SET v2new=645
SET v3new=2
SET bug=SET
(
ECHO #ECHO OFF ^& SETLOCAL
ECHO REM .
ECHO REM version von dolphin
ECHO %bug% v1old=%v1new%
ECHO %bug% v2old=%v2new%
ECHO %bug% v3old=%v3new%
)>newupdate.bat
ECHO %bug% bug=%bug%
PAUSE
EXIT
The batch echo command has a variety of issues displaying certain content. Putting double quotes around the SET statements will resolve the issue you are experiencing. You may also want to change your first file redirection to use > instead of >>, so that the batch file is overwritten each time instead of appended to. Here is the updated code:
#ECHO OFF
SET "v1old=4"
SET "v2old=0"
SET "v3old=7453"
SET "v1new=8"
SET "v2new=645"
SET "v3new=2"
ECHO #ECHO OFF ^& SETLOCAL>newupdate.bat
ECHO REM .>>newupdate.bat
ECHO REM version von dolphin>>newupdate.bat
ECHO SET "v1old=%v1new%">>newupdate.bat
ECHO SET "v2old=%v2new%">>newupdate.bat
ECHO SET" v3old=%v3new%">>newupdate.bat
PAUSE
EXIT
This is happening because v3new is 2. So you are directing STDERR to newupdate.bat. Easy way for you to see that is to temporarily comment out the #ECHO OFF and you will see that the line in question expands to
ECHO SET v3old= 2>>newupdate.bat
#Seth has good suggestions but you will still have the problem. Inserting a space between > and newupdate.bat in each case would solve the problem.
I have a dos batch file.
mycommand.exe>c:\temp
find /B Serv c:\temp>c:\temp2
set /p var1=<c:\temp2
SET var2=%var1:~-7%
echo %var2%
This is only DOS, not windows environment.
The problem is that, the batch file output is:
"Echo is ON". Can't echo the VAR2 variable.
mycommand.exe is a simple app. Not important.
> type c:\temp"
VERSION 45.2
TAG1 NUMBER is 1234567
Serv NUMBER is 9654754
> type c:\temp2
c:temp Serv NUMBER is 9654754
What can I do, If I would like echo the VAR2 variable?
I can't use "setlocal enabledelayedexpansion" because setlocal "Command or filename not recognized".
Edit: What am I want exactly?
I would like to ECHO mycommand.exe output 3rd line last 7 characthers. Thats all.
"good old DOS" is old, but not very good.
Your problem can be solved, basicly by building a temporary .bat file.
It's described in detail here:
https://support.microsoft.com/en-us/kb/66292
I have no DOS available, so I can't test, but this should work for you:
mycommand.exe>c:\temp.txt
find "Serv " c:\temp.txt>c:\temp2.txt
REM init.txt should already exist
REM to create it:
REM COPY CON INIT.TXT
REM SET VARIABLE=^Z
REM ( press Ctrl-Z to generate ^Z )
REM
REM also the file "temp2.txt" should exist.
copy init.txt+temp2.txt varset.bat
call varset.bat
for %%i in (%variable%) do set numb=%%i
echo Server number is: %numb%
REM just because I'm curious, does the following work? :
set var2=%variable%
echo var2 is now %var2%
The manual creation of init.txt has to be done once only, if you can live with, that it always creates a variable with the same name (therefore the last two lines, so you could use the same init.txt over and over again - please feedback, whether it works - I'm quite curious)
Bit of a tricky one. How can I correctly escape the following in a batch file?
echo /? display this help text
This particular combination of characters is treated as an "ECHO /?" command:
C:\Batch>ECHO /? display this help text
Displays messages, or turns command-echoing on or off.
ECHO [ON | OFF]
ECHO [message]
Type ECHO without parameters to display the current echo setting.
It does not respond to caret (^) escaping, ie. I've tried ^/? /^? and ^/^?.
NB: As a workaround, I found that inserting other characters in between is enough to bypass the ECHO command line processor, eg:
echo ... /? display this help text
Still, this is not ideal and I wondered if there was a way to acheive the desired output, namely with /? at the start of the echoed message.
For escaping echo arguments exists many variants, like echo., echo:, echo=
But only echo( seems to be secure against any appended text.
These one fails, if files exists like echo, echo[, echo] or echo+
echo.
echo[
echo]
echo+
These one fails, if a file in the current directory exists named my.bat
echo\..\my.bat
echo:\..\my.bat
echo.\..\my.bat
These one fails independet of a file
echo/?
echo,/?
echo;/?
Only the echo( seems to be always safe against any content
For escaping echo arguments, you can use the alternative syntax echo.:
echo./?