Если я использую эти команды таким образом, то они сделают то, что и должны:
Еслиfoo
былранее установленный как одно или другое, он переходит кfoobar_menu
Если foo
было раньшенетустановлено как (то же самое) одно или другое, оно переходит кanother_menu
rem Check if foo was previously set as bar1 or bar2...
if "%foo%"=="bar1" goto :foobar_menu
if "%foo%"=="bar2" goto :foobar_menu
rem Check if foo was NOT previously set as bar1 or bar2...
if not "%foo%"=="bar1" goto :another_menu
if not "%foo%"=="bar2" goto :another_menu
Вот почему это меня сбивает с толку: если я поменяю их местами, как показано ниже, то это не будет работать должным образом, оно перейдет на неправильную метку, но почему?
rem Check if foo was NOT previously set as bar1 or bar2...
if not "%foo%"=="bar1" goto :another_menu
if not "%foo%"=="bar2" goto :another_menu
rem Check if foo was previously set as bar1 or bar2...
if "%foo%"=="bar1" goto :foobar_menu
if "%foo%"=="bar2" goto :foobar_menu
Почему эти две вещи не делают одно и то же?
Это потому, что я не заключаю части goto в скобки?
У меня это работает (первый способ), но это не тот порядок, в котором идут мои меню, и я просто хотел, чтобы все работало так, как показано во втором (нерабочем) примере выше.
Ваше здоровье.
РЕДАКТИРОВАТЬ:
Это фактические команды. Если использовать этот способ, то, хотя он и вложенный, он все равно переходит к метке, choose_audio_sample_rate
даже если opus или libopus установлены под переменной.
if not "%audio_codec%"=="libopus" if not "%audio_codec%"=="opus" goto :choose_audio_sample_rate
if "%audio_codec%"=="libopus" if "%audio_codec%"=="opus" goto :choose_audio_sample_rate_opus
На самом деле, подмененная версия также не работает, она также переходит в состояние, choose_audio_sample_rate
даже если под переменной установлено opus или libopus.
if "%audio_codec%"=="libopus" if "%audio_codec%"=="opus" goto :choose_audio_sample_rate_opus
if not "%audio_codec%"=="libopus" if not "%audio_codec%"=="opus" goto :choose_audio_sample_rate
Я тут в психа превращаюсь, лол. Ладно, это просто сработает (и перейдет прямо в меню не-опуса), если я использую только это:
if "%audio_codec%"=="libopus" (goto :choose_audio_sample_rate_opus)
if "%audio_codec%"=="opus" (goto :choose_audio_sample_rate_opus)
Если это libopus, то он переходит на нужную метку. Если это не libopus, то обрабатывается следующая строка, а если это opus, то он переходит на нужную метку.
Если же он выходил за эти рамки, то он не был ни libopus, ни opus и переходил в общее меню.
решение1
Ваш пакетный файл выполняется сверху вниз.
Во втором примере, даже если установлено foo2
или foo1
, он всегда перейдет к :another_menu
. Единственный способ, которым пакетный файл пройдет мимо этих двух операторов, — это если установлены оба foo1
и .foo2
По сути, вы создаете ситуацию логического ИЛИ.
Если foo1 ИЛИ foo2 не установлены, перейдите в another_menu
ЕЩЕ
Если установлено foo1 ИЛИ foo2, перейдите в foobar_menu
ЕЩЕ
Ничего не делать
В то время как первый пример,
Если установлено foo1 ИЛИ foo2, перейдите в foobar_menu
ЕЩЕ
Если foo1 ИЛИ foo2 не установлены, перейдите в another_menu
ЕЩЕ
Ничего не делать
Вам нужен именно логический AND. Операторы IF в пакетном файле не поддерживают ни AND, ни OR. Поэтому мы вкладываем их или объединяем в цепочку следующим образом:
if not "%foo1%"=="bar1" if not "%foo2%"=="bar2" goto :another_menu
Это говорит, если foo1 не установлен, то если foo2 не установлен, перейдите к :another_menu
Или, проще говоря, если foo1 и foo2 не установлены, перейдите в another_menu
решение2
Вашу логику можно немного упростить, используя findstr
Echo("%foo%"|Findstr /C:"bar1" /C:"bar2" > nul && Goto :FooBarMenu || Goto :AnotherMenu
Логика: Findstr сравнивает строку %foo%
с bar1 и bar2. Если есть совпадение, команда завершается успешно, и условный оператор &&
выполняет следующую команду. Если совпадения нет, ||
условный оператор запускается, выполняя следующую команду, так как предыдущая команда не была выполнена успешно.
Пример:
@Echo off
Set "foo=notbar"
:loop
Echo("%foo%"|Findstr /C:"bar1" /C:"bar2" > nul ^
&& Call :fooBarMenu foobarMenu || Call :AnotherMenu Anothermenu
If not defined foo Exit /B 0
Goto :loop
:foobarmenu
Echo(@ %~1 foo = %foo%
Set "foo="
Exit /B 0
:Anothermenu
Echo(@ %~1 foo = %foo%
Set "foo=bar2"
Exit /B 0
решение3
Вы уже проверили bar1
и bar2
. Поэтому нет необходимости проверять еще раз, НЕ является ли это bar1
или bar2
(это определенно не является таковым, когда поток кода достигает этой точки, потому что вы уже разветвились в другом месте, когда это произошло).
rem Check if foo was previously set as bar1 or bar2...
if "%foo%"=="bar1" goto :foobar_menu
if "%foo%"=="bar2" goto :foobar_menu
rem no need to check if foo was NOT previously set as bar1 or bar2
rem if FOO is anything other than the previously checked values,
rem your code will continue here anyway.
echo FOO isn't bar1 or bar2.
rem Don't forget to end this branch of your code or it will just continue to run:
goto :eof
:foobar_menu
echo reached foobar.
Возможно, вам стоит рассмотреть возможность использования /i
переключателя с if
целью игнорирования заглавных букв
( if "foo"=="FOO"
is false, if /i "foo"=="FOO"
is true)