В скриптах оболочки, если мне нужно запустить команду из каталога, я могу использовать подоболочку, чтобы гарантировать возврат в исходный контекст:
(cd temporary/new/directory ; command)
# now I am still in original directory
Можно ли это сделать в пакетных файлах Windows (или cmd-файлах)?
Если сделать то же самое в пакетных файлах, то я окажусь в новом каталоге.
Я могу сделать:
pushd temporary\new\directory && command && popd
Но popd зависит от успеха command
.
Есть идеи?
решение1
Если вы это сделаете:
pushd \windows && foobar && popd
вы останетесь (как вы и указали) в папке \windows. Попробуйте:
pushd \windows & foobar & popd
и вы вернетесь туда, откуда начали.
решение2
По умолчанию пакетные файлы Windows запускаются в контексте родительской оболочки (что необычно для пользователей Unix, где source
требуется явное указание, но это была единственная возможность в MS-DOS). Это означает, что изменения каталогов и переменных окружения также влияют на исходную интерактивную оболочку.
Поместите setlocal
в начало скрипта, чтобы он работал в своем собственном контексте — cd
после этого вы можете безопасно использовать его внутри скрипта.
решение3
Как уже упоминалось ранее, Grawity pushd \windows && (foobar & popd)
будет работать лучше, чем pushd \windows & foobar & popd
предыдущий, поскольку последний может дать сбой, если такого каталога не будет.
Кроме того, использование setlocal
и endlocal
позволяет иметь несколько локальных сред, например:
setlocal
cd dir
command
endlocal
Теперь вы вернетесь в свой исходный каталог.
решение4
Я приветствую предложение Grawity разместить 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
создает локализованную среду, поэтому любые переменные, которые вы устанавливаете или изменяете в таком блоке, вернутся к своему предыдущему значению после endlocal
.