The command line
if %test% == "ac3" echo true
is preprocessed by Windows command interpreter before execution of IF command to
if ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my movie (2017).mkv" == "ac3" echo true
A space character outside a double quoted string is interpreted as argument separator. For that reason the first argument is for command IF ffprobe
the second argument is -v
and the third argument is error
.
-v
is for command IF an unknown operator and the result is the error message:
-v was unexpected at this time.
The standard solution is double quoting both strings to compare as within a double quoted string a space character as well as &()[]{}^=;!'+,`~|<>
are interpreted as literal characters.
if "%test%" == "ac3" echo true
The command IF compares double quoted strings always with including the double quotes as strings and never runs an integer comparison on using double quotes on any side.
But in this case using if "%test%" == "ac3"
echo true also does not work as expected because the executed command line is:
if "ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my movie (2017).mkv"" == "ac3" echo true
Now the first IF argument is "ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my
and second argument is movie
resulting in error message:
movie was unexpected at this time.
It is necessary to use delayed environment variable expansion with a string containing double quotes assigned to an environment variable and compared with another string with IF command.
set "test=ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my movie (2017).mkv""
setlocal EnableDelayedExpansion
if "!test!" == "ac3" echo true
endlocal
See also the answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? why using set "test=..."
and read this answer for details about the commands SETLOCAL and ENDLOCAL.
However, the goal is to compare the output of console executable ffprobe
with the string ac3
.
This requires the usage of FOR.
for /F "delims=" %%I in ('ffprobe.exe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my movie (2017).mkv" 2^>^&1') do if /I "%%I" == "ac3" echo true
Command FOR runs the command line as specified between '
...'
in a separate command process started with cmd.exe /C
in background without opening a window and captures all output written to handle STDOUT for processing this output line by line whereby empty lines and lines starting with a semicolon are ignored.
2>&1
results in output of ffprobe.exe
written to handle STDERR being redirected also in the background command process to handle STDOUT for being also captured and processed by FOR.
The redirection operators >
and &
must be escaped here both with caret character ^
to be interpreted first as literal characters when Windows command interpreter parses the entire FOR command line.
I don't have installed ffprobe.exe
and so could not test the entire FOR command line. But the FOR command line should work in case of ffprobe.exe
outputs really just ac3
to either STDOUT or STDERR and nothing else. The output of ffprobe.exe
enclosed in double quotes is compared case-insensitive with "ac3"
.
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.
endlocal /?
for /?
if /?
set /?
setlocal /?
Read also the Microsoft documentation about Using command redirection operators.