18

В сценариях оболочки, если мне нужно запустить команду из каталога, я могу использовать подоболочку, чтобы вернуться в исходный контекст:

(cd temporary/new/directory ; command)
# now I am still in original directory

Это можно сделать в пакетных файлах Windows (или cmd-файлах)

То же самое в пакетных файлах оставляет меня в новом каталоге.

Я могу сделать:

pushd temporary\new\directory && command && popd

Но попд зависит от успеха command .

Есть идеи?

6 ответов6

20

Если вы делаете:

pushd \windows && foobar && popd

Вы останетесь (как вы заявляете) в папке \windows. Пытаться:

pushd \windows & foobar & popd

и ты должен вернуться туда, откуда начал.

14

По умолчанию пакетные файлы Windows запускаются в контексте родительской оболочки (что необычно для пользователей Unix, где требуется явный source , но была единственной возможностью в MS-DOS). Это означает, что изменения каталога и переменные среды также влияют на оригинальную интерактивную оболочку.

Поместите setlocal вверху вашего скрипта, чтобы он работал в своем собственном контексте - тогда вы можете безопасно использовать cd внутри скрипта.

3

Вы можете использовать cd - чтобы вернуться к предыдущему рабочему каталогу. И использовать ; вместо && последующие команды не будут зависеть от успеха предыдущих команд.

$ pwd
/etc
$ cd /var ; pwd ; cd -
/var
$ pwd
/etc
3

Как упоминалось выше, pushd \windows && (foobar & popd) будет работать лучше, чем pushd \windows & foobar & popd потому что последний может потерпеть неудачу, если такой директории нет.

Кроме того, использование setlocal и endlocal позволяет вам иметь несколько локальных сред, например, вы можете иметь:

setlocal

cd dir

command

endlocal

Теперь вы вернетесь в исходный каталог.

1

Я приветствую предложение Гравити поставить setlocal в начале вашего пакетного скрипта, но я бы добавил тот факт, что вы можете иметь несколько вложенных блоков setlocal / endlocal , так что более уместным ответом на вопрос может быть

@echo off
setlocal
cd dir1
  ...
setlocal
cd dir2
command
endlocal
:: Now I am back in dir1
  ...

И, конечно, если вы хотите, чтобы команда выполнялась только в том случае, если cd to dir2 успешен, произнесите cd dir2 && command .

Обратите внимание, что блок setlocal / endlocal создает локализованную среду, поэтому любые переменные, которые вы устанавливаете или изменяете в таком блоке, возвращаются к своему предыдущему значению после endlocal .

0

Вы можете сохранить текущий каталог в переменную. Измените и измените обратно в зависимости от возвращаемого значения команды. Кстати,% CD% возвращает ваш текущий DIR.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .