Как изменить текущий каталог внутри оператора IF и сослаться на его путь с помощью переменной среды CD?
Я пытаюсь установить приложение с моего компьютера под управлением Windows 10, используя adb, и мне нужно использовать команду cd
перед установкой приложения.
Но я вижу странное поведение. Если я использую cd
команда перед if
Скажите, это работает хорошо. Но если я использую cd
командование внутри if
Скажите, это не работает.
Вот что я попробовал:
Этот работает хорошо:
cd %~f0\..\..\apps\app_sample\samples\sample_app\build\outputs\apk if "%arg1%" == "aaa" ( adb install %CD%\sample_app-debug.apk )
Это приводит к выполнению в ошибке:
if "%arg1%" == "aaa" ( cd %~f0\..\..\apps\app_sample\samples\sample_app\build\outputs\apk adb install %CD%\sample_app-debug.apk )
Вывод ошибки:
Не удалось стат
C: \ Users \ ntuser \ Documents \ рабочее пространство \ команда \ скрипт \ sample_app-debug.apk:
Данный файл или каталог отсутствуетПохоже, он не сделал
cd
Команда в этом случае.
1 ответ
Всякий раз, когда интерпретатор команд Windows cmd.exe
встречает начало командного блока, начинающегося с (
и заканчивая сопоставлением )
весь блок предварительно обрабатывается перед тем, как команда, оставленная командному блоку, будет выполнена вообще. Это означает, что все переменные среды, использующие %variable%
синтаксис заменяется текущим значением указанной переменной среды перед выполнением команды, которая впоследствии выполняет весь командный блок. Такое поведение можно увидеть при запуске командного файла из окна командной строки без @echo off
будучи обычно наверху командного файла.
Это означает, что для вашего командного файла с командой IF и командным блоком нужно выполнить при условии, что это правда, что %CD%
заменяется текущим каталогом перед выполнением команды IF, а также перед тем, как команда CD будет выполнена вообще.
Есть две возможности:
- явно включить отложенное расширение переменной среды и ссылаться на переменную среды в командном блоке с использованием синтаксиса
!variable!
или же - не используйте командный блок с помощью GOTO или подпрограммы и CALL.
Решение 1 с включенным отложенным расширением переменной среды:
setlocal EnableDelayedExpansion
if "%arg1%" == "aaa" (
cd "%~dp0..\apps\app_sample\samples\sample_app\build\outputs\apk"
adb.exe install "!CD!\sample_app-debug.apk"
)
endlocal
Решение 2 с тем, чтобы вообще не использовать командный блок и вместо этого использовать GOTO:
if "%arg1%" == "aaa" goto AAA
rem Other commands
goto :EOF
:AAA
cd "%~dp0..\apps\app_sample\samples\sample_app\build\outputs\apk"
adb.exe install "%CD%\sample_app-debug.apk"
goto :EOF
rem Or use a different GOTO to continue processing somewhere else in batch file.
Другое решение 2 использует подпрограмму и команду CALL:
if "%arg1%" == "aaa" call :AAA
rem Other commands executed even if above condition is true.
rem Avoid a fall through to the subroutine below.
goto :EOF
:AAA
cd "%~dp0..\apps\app_sample\samples\sample_app\build\outputs\apk"
adb.exe install "%CD%\sample_app-debug.apk"
rem Exit the subroutine and continue on line below calling it.
goto :EOF
Но я думаю, что ваш код может быть еще проще, потому что, скорее всего, нет необходимости указывать файл *.apk с полным путем.
if "%arg1%" == "aaa" (
cd "%~dp0..\apps\app_sample\samples\sample_app\build\outputs\apk"
adb.exe install sample_app-debug.apk
)
И, возможно, также работает это:
if "%arg1%" == "aaa" adb.exe install "%~dp0..\apps\app_sample\samples\sample_app\build\outputs\apk\sample_app-debug.apk"
Лучше использовать здесь %~dp0
который ссылается на диск и путь пакетного файла, заканчивающийся обратной косой чертой вместо %~f0
который является именем командного файла с расширением файла и полным путем.
Например, с командным файлом C:\Temp\Test\Install.bat
командная строка
cd "%~f0\..\..\apps\app_sample\samples\sample_app\build\outputs\apk"
приводит к выполнению
cd "C:\Temp\Test\Install.bat\..\..\apps\app_sample\samples\sample_app\build\outputs\apk"
и текущий каталог C:\Temp\apps\app_sample\samples\sample_app\build\outputs\apk
после этой команды с действительно неверным именем каталога Install.bat
в пути, который не является каталогом.
Командная строка
cd "%~dp0..\apps\app_sample\samples\sample_app\build\outputs\apk"
намного лучше, так как это приводит к выполнению
cd "C:\Temp\Test\..\apps\app_sample\samples\sample_app\build\outputs\apk"
что делает также C:\Temp\apps\app_sample\samples\sample_app\build\outputs\apk
текущий каталог, но с совершенно правильным путем по сравнению с указанным выше cd
командная строка.
Чтобы понять используемые команды и то, как они работают, откройте окно командной строки, выполните там следующие команды и полностью прочитайте все страницы справки, отображаемые для каждой команды.
call /?
... объясняет%~dp0
а также%~f0
,cd /?
endlocal /?
goto /?
if /?
rem /?
set /?
... объясняет задержку расширения переменной среды на примере IF и FOR.setlocal /?
У меня не установлен ADB. Так что я могу только предположить, что это исполняемый файл с расширением файла .exe
а не командный файл с расширением файла .bat
или же .cmd
что потребует использования call adb.bat ...
или же call adb.cmd ...
в этом командном файле.