I suggest following batch file code for this task:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "HostsFile=%SystemRoot%\System32\drivers\etc\hosts"
if not "%ProgramFiles(x86)%" == "" if exist %SystemRoot%\Sysnative\cmd.exe set "HostsFile=%SystemRoot%\Sysnative\drivers\etc\hosts"
if not exist %HostsFile% goto AppendData
%SystemRoot%\System32\findstr.exe /I /L /C:"foo" %HostsFile% >nul
if not errorlevel 1 goto EndBatch
%SystemRoot%\System32\findstr.exe /R /V "$" %HostsFile% >nul
if not errorlevel 1 echo/>>%HostsFile%
:AppendData
>>%HostsFile% echo 8.8.8.8 foo
:EndBatch
endlocal
The third line defines the environment variable HostsFile
with standard file path which is right on batch file being executed on 32-bit Windows by 32-bit cmd.exe
or on 64-bit Windows by 64-bit cmd.exe
in directory %SystemRoot%\System32
.
The fourth line takes into account the Windows File System Redirector according to WOW64 Implementation Details. The batch file is executed on 64-bit Windows if there is defined an environment variable with name ProgramFiles(x86)
with a non-empty value. But the batch file is executed by 32-bit cmd.exe
in directory %SystemRoot%\SysWOW64
if there is %SystemRoot%\Sysnative\cmd.exe
. The redirector Sysnative
does not exist for x64 applications. In this case the file hosts
must be referenced from within 32-bit environment on 64-bit Windows with using the Sysnative
redirector in file path.
Next is checked if the file hosts
exists at all. If the file does not exist, the data line to append can be directly written to the file without any further checks whereby the file hosts
is created in this case.
Otherwise the command FINDSTR is used to search case-insensitive with a literally interpreted search string for foo
with redirecting the perhaps found line(s) to device NUL. FINDSTR exits with value 0
if there is at least one positive match and with value 1
if the searched string could not be found on any line.
if not errorlevel 1
means IF exit code is NOT GREATER OR EQUAL 1, or in other words LOWER THAN 1, or in this case EQUAL 0 because of FINDSTR never exits with a negative value as nearly all applications and commands. So if this condition is true, the file hosts
contains at least once the searched string and nothing to change on file.
Otherwise FINDSTR is used once more to search this time with a regular expression for end of line and to output all lines not having a line ending because of option /V
. So if last line in file hosts
has no line ending, FINDSTR exits with value 0
because of having output one line with no line ending whereby this output is redirected to device NUL.
A line ending is appended to file hosts
if FINDSTR exited with value 0
because of file hosts
ends with no line ending before appending next the data line to add to this file.
The code above does not work if the batch file is not executed with elevated permissions of a local administrator or the file hosts
has read-only attribute set or is otherwise protected against modification by a script.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
findstr /?
goto /?
if /?
set /?
setlocal /?
See also DosTips forum topic: ECHO. FAILS to give text or blank line - Instead use ECHO/