As we all know, if Echo follows an environment variable, but the variable is empty, the equivalent of an echo without any arguments, that is, whether the current echo is on or off. Many articles or tutorials offer solutions that add a dot echo behind the echo, which will output blank lines.
Copy Code code as follows:
@echo off
Echo%demon.tw%
:: ECHO is off.
echo.%demon.tw%
Pause as far as I know, there are at least 10 ways to output empty lines with the Echo:
Copy Code code as follows:
@echo off
echo=
Echo
Echo
echo+
echo/
echo[
Echo
Echo
Echo.
Echo\
Pause
These 10 methods can be divided into three groups, the efficiency of each group decreases in descending order. Sadly, the classic tutorials give the echo in the lowest-efficiency group.
echo. Not only inefficient, but also easy to raise errors:
Copy Code code as follows:
@echo off
CD. >echo
Echo.
Pause
I know it's hard for you to accept, but that's true.
In the first group, after Echo, which is the delimiter in the batch, CMD can parse the echo command correctly and take =, as an argument to the echo command. Yes, you're right. Delimiters are not used to separate commands and parameters, they are usually part of the parameters. Since it is a parameter, then why not be output? That's because the echo command skips the first character of the argument, starts the output from the second character, and the second character is nul, so the blank line is output.
You may have to ask, then why use a space as a separator but not output empty line? That's because before the output, cmd to check if the parameters of the echo command are on or off, or if the argument is null: first skip all white-space characters, and if the string ends after skipping, think that without the argument, the output echo is on or off, and if the string does not end, The WCSNICMP function is invoked to determine whether the remaining string is on or off, thereby modifying the state of the Echo.
So adding a lot of space is the same effect:
Copy Code code as follows:
@echo off
Echo
echo on
Echo
Pause
And for the second and third groups, things are not so simple, because the echo is not followed by the separator, so parsing will be treated as a whole, and echo+ echo/and so on is obviously not internal command, CMD will take them as an external command to search. Well, you know, search takes time, and that's why they're less efficient than the first group.
Unfortunately, Cmd spent a lot of effort searching, but still can't find such an external command, this time it will try to fix (fix) command to see if there are some characters (figure):
As you can see, cmd:. \ 's processing is not the same as +[]/, if it is +[]/,cmd will be directly removed from the command and added to the previous parameter, and if it is:. \ and cmd expansion is open, Then call one more time the GetFileAttributes function gets the file attributes, and calling the function more than once will naturally take some more time, so the third group is slightly less efficient than the second group.
Let's explain why echo sometimes causes errors. The file name does not appear:. \, theoretically the GetFileAttributes function should return-1 (invalid_file_attributes), but that is not the case, I don't know if that counts as a getfileattributes function bug:
Copy Code code as follows:
#include <stdio.h>
#include <windows.h>
int main ()
{
FILE *FP = fopen ("echo", "WB");
Fclose (FP);
printf ("0x%x\n", GetFileAttributes ("Echo:"));
printf ("0x%x\n", GetFileAttributes ("echo."));
printf ("0x%x\n", GetFileAttributes ("echo/"));
return 0;
}
If you test the C program above, you'll find echo. That line returns 1.
If the GetFileAttributes function returns no-1 (which generally means that the file does not exist) and is not a 0x10 (indicating that the file is a folder), then the command remains the same as the external command.
Copy Code code as follows:
@echo off
CD. >echo
Echo.
Pause
' Echo. ' is not recognized as a internal or external command, operable program or batch file.
Copy Code code as follows:
@echo off
CD. >echo
Setlocal disableextensions
Echo.
Pause
Shut down the CMD expansion, no problem.
Copy Code code as follows:
@echo off
MD Echo
Echo.
Pause
Echo is a folder, not a file, no problem.
To conclude, in most cases, you should use the first group of Echo, Echo; echo= to output, they are as efficient as echo (space), and can be used to output on or off, and to output blank lines when the variable is empty.
But Echo, Echo; Echo= can not output lines that begin with/, and if you need to, use the second set of echo+ echo/echo[Echo], which is less efficient but guarantees the output as it is.
I do not recommend you to use the third group of Echo:echo. Echo\, if you still want to use it like a garbage tutorial, I have no choice.
Author: Demon
Link: http://demon.tw/reverse/cmd-internal-echo.html