Временно изменить каталог для одной команды пакетного файла
В сценариях оболочки, если мне нужно выполнить команду из каталога, я могу использовать подоболочку, чтобы вернуться в исходный контекст:
(cd temporary/new/directory ; command)
# now I am still in original directory
Это можно сделать в пакетных файлах Windows (или cmd-файлах)
То же самое в пакетных файлах оставляет меня в новом каталоге.
Я могу сделать:
pushd temporary\new\directory && command && popd
Но попд зависит от успеха command
,
Есть идеи?
6 ответов
Если вы делаете:
pushd \windows && foobar && popd
Вы останетесь (как вы заявляете) в папке \windows. Пытаться:
pushd \windows & foobar & popd
и ты должен вернуться туда, откуда начал.
По умолчанию пакетные файлы Windows запускаются в контексте родительской оболочки (что необычно для пользователей Unix, где явное source
нужна, но была единственная возможность в MS-DOS). Это означает, что изменения каталога и переменные среды также влияют на оригинальную интерактивную оболочку.
Положил setlocal
в верхней части вашего скрипта, чтобы он работал в своем собственном контексте - вы можете безопасно использовать cd
тогда внутри скрипта.
Как упоминалось ранее, pushd \windows && (foobar & popd)
будет работать лучше, чем pushd \windows & foobar & popd
потому что последний может потерпеть неудачу, если такой директории нет.
Кроме того, используя setlocal
а также endlocal
позволяет иметь несколько локальных сред, например, вы можете иметь:
setlocal
cd dir
command
endlocal
Теперь вы вернетесь в исходный каталог.
Ты можешь использовать cd -
чтобы вернуться к предыдущему рабочему каталогу. И использовать ;
вместо &&
, то последующие команды не будут зависеть от успеха предыдущих команд.
$ pwd
/etc
$ cd /var ; pwd ; cd -
/var
$ pwd
/etc
Я приветствую предложение Гравити поставить setlocal
в начале вашего пакетного сценария, но я бы добавил тот факт, что вы можете иметь несколько вложенных, setlocal
/ endlocal
блоки, поэтому более актуальным ответом на вопрос может быть
@echo off
setlocal
cd
dir1
...
setlocal
cd
dir2
command
endlocal
:: Now I am back in
dir1
...
И, конечно же, если вы хотите, чтобы команда выполнялась только в том случае, если cd
в dir2
успешно, скажем cd
dir2
&&
command
,
Обратите внимание, что setlocal
/ endlocal
block создает локализованную среду, поэтому любые переменные, которые вы устанавливаете или изменяете в таком блоке, возвращаются к своему предыдущему значению после endlocal
,
Вы можете сохранить текущий каталог в переменную. Измените и измените обратно в зависимости от возвращаемого значения команды. Кстати, %CD% возвращает ваш текущий DIR.