I'm having a problem with what seems like it should be a fairly basic piece of a script.
ECHO !url1! >> !hostsfile! && ECHO Successfully added !url1! to file. || 2>&1>NUL && ECHO Unable to write !url1! to file. && GOTO :FAIL
It's a conditional that tries to write a URL to a given file, and if access to that file is denied, prints an error message. Unfortunately, CMD also generates its own error message, so at the moment, as output, I'm getting the default error "Access denied" followed by my own "Unable to write www.url.com to file."
I've tried without luck to pipe the default error message to NUL, but even with all my reading up on it, my knowledge on how piping works and the syntax for it is still sparse, and I'm not getting anywhere.
Also, as an aside: is there any way to split that line to be more manageable without causing errors?
Trying stuff like:
ECHO !url1! >> !hostsfile! && ECHO Successfully added !url1! to Hosts file.
|| 2>&1>NUL && ECHO Unable to write !url1! to Hosts. && GOTO :FAIL
or
ECHO !url1! >> !hostsfile! && ECHO Successfully added !url1! to Hosts file. ||
2>&1>NUL && ECHO Unable to write !url1! to Hosts. && GOTO :FAIL
...results in "unexpected character" errors.
NB. Exclamation marks are being used for variables because of delayed expansion.
There are several issues:
2>&1>NUL
is invalid redirection syntax, you cannot concatenate multiple redirection operators like that. I assume you want to redirect the STDERR stream to the nul
device, so it should read 2>nul
or 2> nul
.2>&1>NUL
, but there is no command.echo
command does actually not produce the error message Access is denied.
, it is caused by a failed redirection. Therefore you must enclose the redirected echo
command in parentheses in order to be able to suppress the error message by the 2> nul
redirection.echo
command itself does not set the ErrorLevel
pseudo-variable nor the exit code1. However, a failed redirection (<
, >
, >>
) sets the exit code, which is what you are interested in.goto
command is only executed in the ||
branch, so you should put that entire portion in between parentheses.echo Text > file.ext
, the SPACE in between Text
and >
is also output. To avoid that, either simply remove it like echo Text>file.ext
, place a pair of parentheses around the echo
command like (echo Text) > file.ext
, or revert the syntax like > file.ext echo Text
(which is the way I prefer as it is the most general one).echo Text & goto :LABEL
, the SPACE in front of &
is output as well. To avoid that, remove it, or enclose the echo
part within parentheses.cmd
that the two lines belong together. Line continuation is done by ending a line with a caret ^
, so the next one is concatenated2. The next line should be preceded by (at least) a SPACE. Alternatively, parenthesised blocks of code may span multiple lines, so you could also end the first line like ... || (
and have the next line like ... )
for them to be considered as a single command line.Here is the fixed code:
(>> "!hostsfile!" echo !url1!) 2> nul && (echo Successfully added !url1! to file.) || (echo Unable to write !url1! to file.& goto :FAIL)
Or (using line continuation):
(>> "!hostsfile!" echo !url1!) 2> nul && (echo Successfully added !url1! to file.) ^
|| ((echo Unable to write !url1! to file.) & goto :FAIL)
Or even (using parenthesised blocks):
(>> "!hostsfile!" echo !url1!) 2> nul && (
echo Successfully added !url1! to file.
) || (
echo Unable to write !url1! to file.
goto :FAIL
)
1) These two values are almost always are the same, but there are rare cases where they differ; the &&
and ||
operators do actually not care about ErrorLevel
, they rather use the exit code.
2) The trailing caret ^
lets cmd
ignore the next line-break and escape the following character, so two lines echo A^
and & echo B
cause the output A& echo B
as the &
appears escaped; to achieve two lines of output A
and B
, change the second line to SPACE + & echo B
, so the SPACE is escaped but the ampersand is not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With