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?


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ś.


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.


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.


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

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.


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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.