Tymczasowo zmień katalog dla pojedynczego polecenia pliku wsadowego

19

Jeśli w skryptach powłoki muszę uruchomić polecenie z katalogu, możemy użyć podpowłoki, aby upewnić się, że wrócę do pierwotnego kontekstu:

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

Czy można to zrobić w plikach wsadowych systemu Windows (lub plikach cmd)

Robienie tego samego w plikach wsadowych pozostawia mnie w nowym katalogu.

Mogę zrobić:

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

Ale tata zależy od sukcesu command.

Jakieś pomysły?

Greg
źródło
Jak wywołujesz „plik wsadowy” lub „plik cmd”? Jeśli umieścisz polecenie cd w skrypcie powłoki i uruchomisz ten skrypt (nie źródłowy), bieżący katalog roboczy powłoki wywołującej się nie zmieni.
garyjohn
Dla jasności odnosi się to do plików wsadowych systemu Windows.
Greg
Jest to skrypt, który uruchamia kilka poleceń w różnych częściach drzewa katalogów. Niektóre polecenia działają tylko w bieżącym katalogu. Powrót do oryginalnego katalogu pomaga uprościć dane sterujące skryptem. Czy sugerujesz utworzenie osobnego pliku wsadowego dla każdego katalogu, w którym muszę nawiązywać połączenia?
Greg
O ile pamiętam, odwoływałeś się do skryptów powłoki i nie wspomniałeś o Windows w swoim pierwotnym pytaniu, więc błędnie założyłem, że używasz systemu podobnego do Uniksa. Teraz rozumiem.
garyjohn
Tak, przepraszam, zdaję sobie sprawę, że nie było jasne (chociaż myślę, że „plik wsadowy” był wskazówką :-p)
Greg

Odpowiedzi:

21

Jeśli zrobisz:

pushd \windows && foobar && popd

pozostaniesz (jak twierdzisz) w folderze \ windows. Próbować:

pushd \windows & foobar & popd

i powinieneś znaleźć się tam, gdzie zacząłeś.

BillP3rd
źródło
1
Ach, więc pojedynczy ampersand jest odpowiednikiem średnika w sh. To idealne. (i odniesienie: ss64.com/nt/syntax-conditional.html )
Greg
6
Warto pamiętać, że cd/ pushdczasem się nie udaje (na przykład, jeśli katalog nie istnieje). pushd \windows && (foobar & popd)może być bardziej niezawodny
użytkownik1686,
16

Domyślnie pliki wsadowe systemu Windows są uruchamiane w kontekście powłoki nadrzędnej (co jest niezwykłe dla użytkowników Uniksa, gdzie sourcekonieczne jest użycie jawnego , ale było to jedyną możliwością w MS-DOS). Oznacza to, że zmiany katalogów i zmienne środowiskowe również wpływają na oryginalną powłokę interaktywną.

Umieść setlocalna górze skryptu, aby działał we własnym kontekście - wtedy możesz bezpiecznie korzystać cdze skryptu.

użytkownik1686
źródło
Dzięki, to brzmi jak to, czego potrzebuję - sprawdzę to, gdy uzyskam dostęp do komputera z systemem Windows. Czy wpłynęłoby to na polecenia podrzędne za pomocą nawiasów?
Greg
1
@Greg: Wydaje się, że ( )tylko polecenia grupują razem, ale nadal uruchamiają je w kontekście nadrzędnym. (setlocal & cd foo & bar)nie będzie działać; zamiast tego pushd foo && (bar & popd)byłoby potrzebne.
user1686
4

Jak już wcześniej wspomniano grawitacja, pushd \windows && (foobar & popd)działałaby lepiej niż pushd \windows & foobar & popddlatego, że ta ostatnia może zawieść, jeśli nie ma takiego katalogu.

Ponadto używanie setlocali endlocalpozwala mieć wiele lokalnych środowisk, więc na przykład możesz mieć:

setlocal

cd dir

command

endlocal

Teraz wrócisz do oryginalnego katalogu.

Timtech
źródło
3

Możesz użyć, cd -aby wrócić do poprzedniego katalogu roboczego. I użyj ;zamiast &&, wtedy kolejne polecenia nie będą zależeć od powodzenia poprzednich poleceń.

$ pwd
/etc
$ cd /var ; pwd ; cd -
/var
$ pwd
/etc
bahamat
źródło
Zaktualizowałem pytanie, aby wyjaśnić, że pytam o skrypty wsadowe / powłoki systemu Windows. Wiem, jak to zrobić pod skorupą podobną do sh :)
Greg
Jak wskazał BillP3rd, odpowiednik „;” w plikach wsadowych jest „&”.
Greg
O przepraszam. Twoje użycie ukośników sprawiło, że pomyślałem, że to UNIX.
bahamat
1

Pochwalam sugestię grawitacji, aby umieścić setlocalna początku skryptu wsadowego, ale dodam fakt, że możesz mieć wiele, zagnieżdżonych setlocal/ endlocalbloków, więc bardziej trafną odpowiedzią na pytanie może być

@echo off
setlocal
cddir1
  ...
setlocal
cddir2
command
endlocal
:: Now I am back indir1
  ...

I, oczywiście, jeśli chcesz polecenie należy wykonać tylko wtedy, gdy cdsię dir2to uda, powiedzmy .cddir2&&command

Zauważ, że setlocal/ endlocalblock tworzy zlokalizowane środowisko, więc wszelkie zmienne, które ustawisz lub zmienisz w takim bloku, powrócą do poprzedniej wartości po endlocal.

Scott
źródło
0

Możesz zapisać bieżący katalog w zmiennej. Zmień i cofnij w zależności od zwracanej wartości polecenia. BTW,% CD% zwraca bieżący DIR.

surfasb
źródło