Jak korzystać z poleceń pushd i popd?


332

Jakie są praktyczne zastosowania obu pushdi popdkiedy istnieje korzyść z używania tych dwóch poleceń ponad cdi cd -?

EDYCJA : Szukam kilku praktycznych przykładów użycia obu tych poleceń lub powodów utrzymywania stosu w katalogach (gdy masz uzupełnienie tabulacji cd -, aliasy dla skrócenia cd ..itp.).

Odpowiedzi:


304

pushd, popdI dirssą builtins powłoki, które pozwalają manipulować stos katalogów . Można tego użyć do zmiany katalogów, ale powrotu do katalogu, z którego przyszedłeś.

Na przykład

uruchom z następującymi katalogami:

$ ls
dir1  dir2  dir3

pushd do dir1

$ pushd dir1
~/somedir/dir1 ~/somedir
$ dirs
~/somedir/dir1 ~/somedir

dirspolecenie potwierdza, że ​​mamy teraz na stosie 2 katalogi. dir1i oryginalny reż somedir.

pushd do ../dir3 (ponieważ teraz jesteśmy w środku dir1)

$ pushd ../dir3
~/somedir/dir3 ~/somedir/dir1 ~/somedir
$ dirs
~/somedir/dir3 ~/somedir/dir1 ~/somedir
$ pwd
/home/saml/somedir/dir3

dirspokazuje, że mamy teraz 3 katalogi na stosie. dir3, dir1i somedir. Zwróć uwagę na kierunek. Każdy nowy katalog jest dodawany po lewej stronie. Kiedy zaczniemy wyrzucać katalogi, będą one również przychodzić z lewej strony.

ręcznie zmień katalogi na ../dir2

$ cd ../dir2
$ pwd
/home/saml/somedir/dir2
$ dirs
~/somedir/dir2 ~/somedir/dir1 ~/somedir

Teraz zacznij otwierać katalogi

$ popd
~/somedir/dir1 ~/somedir
$ pwd
/home/saml/somedir/dir1

Zauważ, że wróciliśmy do dir1.

Pop ponownie ...

$ popd
~/somedir    
$ pwd
/home/saml/somedir

I wracamy do punktu wyjścia, somedir.

Może się trochę mylić, ale na szczycie stosu znajduje się katalog, w którym aktualnie się znajdujesz. Stąd, kiedy wrócimy do somedir, chociaż dirspokazuje to:

$ dirs
~/somedir

Nasz stos jest właściwie pusty.

$ popd
bash: popd: directory stack empty

19
Dzięki, całkowicie rozumiem pojęcie stosu i jak działają te polecenia. Jednak szukam kilku praktycznych powodów, aby trzymać stos z katalogami (gdy masz uzupełnienie tabulacji cd -, aliasy dla skrócenia cd ..itp.).
syntagma

21
Często używam pushd& popdw skryptach b / c ratują mnie od konieczności pamiętania, skąd pochodzę, zawsze mogę po prostu popdwrócić z miejsca, z którego przyszedłem. Zazwyczaj robię to, popd >/dev/null 2>&1żeby to uciszyć. Używam cd- codziennie w mojej powłoce. Istnieje kilka innych wskazówek, oszczędzając czas w tym artykule, a także: thegeekstuff.com/2008/10/... .
slm

2
@Garrett - żaden, który mogę sobie wyobrazić.
slm

4
@Garrett @slm, ponieważ cd -śledzi tylko ostatni katalog, wyobrażam sobie, że możliwe są problemy, jeśli wywołasz funkcję, która również zmienia katalog wewnętrznie. w takim przypadku funkcja zakończy się resetowaniem - do bieżącego katalogu, a nie katalogu, do którego chcesz wrócić. pushd / popd jest najbezpieczniejszą metodą. Uwaga: nie przetestowałem mojej teorii.
Binarny Phile

5
Dlaczego nie wrócić do ~/somedir/dir3pierwszego popd?
ziyuang

198

Istnieje bardzo przydatny przypadek użycia pushdi popdpolecenia do pracy z kilkoma folderami jednocześnie.

Możesz bardzo łatwo poruszać się po stosie, ponieważ jest on wyliczony. Oznacza to, że możesz mieć do dyspozycji kilka folderów roboczych podczas pracy.

Zobacz prosty przykład poniżej.


Najpierw stwórzmy przykładową strukturę folderów.

    user@vb:~$ mkdir navigate
    user@vb:~/navigate$ mkdir dir1
    user@vb:~/navigate$ mkdir dir2
    user@vb:~/navigate$ mkdir dir3

Następnie możesz dodać wszystkie swoje foldery do stosu:

    user@vb:~/navigate$ pushd dir1/
    ~/navigate/dir1 ~/navigate
    user@vb:~/navigate/dir1$ pushd ../dir2/
    ~/navigate/dir2 ~/navigate/dir1 ~/navigate
    user@vb:~/navigate/dir2$ pushd ../dir3/
    ~/navigate/dir3 ~/navigate/dir2 ~/navigate/dir1 ~/navigate

Możesz to sprawdzić:

    user@vb:~/navigate/dir3$ dirs -v
     0  ~/navigate/dir3
     1  ~/navigate/dir2
     2  ~/navigate/dir1
     3  ~/navigate

Aby bezpiecznie nawigować, musisz dwukrotnie dodać ostatni (zero) folder, ponieważ zawsze będzie on przepisany:

    user@vb:~/navigate/dir3$ pushd .
    user@vb:~/navigate/dir3$ dirs -v
     0  ~/navigate/dir3
     1  ~/navigate/dir3
     2  ~/navigate/dir2
     3  ~/navigate/dir1
     4  ~/navigate

Teraz możesz przeskakiwać przez te foldery i pracować ze stosem jak z aliasami dla folderów. Myślę, że następująca część jest oczywista:

    user@vb:~/navigate/dir3$ cd ~4
    user@vb:~/navigate$ dirs -v
     0  ~/navigate
     1  ~/navigate/dir3
     2  ~/navigate/dir2
     3  ~/navigate/dir1
     4  ~/navigate
    user@vb:~/navigate$ cd ~3
    user@vb:~/navigate/dir1$ dirs -v
     0  ~/navigate/dir1
     1  ~/navigate/dir3
     2  ~/navigate/dir2
     3  ~/navigate/dir1
     4  ~/navigate
    user@vb:~/navigate/dir1$ touch text.txt
    user@vb:~/navigate/dir1$ cp text.txt ~2
    user@vb:~/navigate/dir1$ ls ~2
    text.txt
    user@vb:~/navigate/dir1$ dirs -v
     0  ~/navigate/dir1
     1  ~/navigate/dir3
     2  ~/navigate/dir2
     3  ~/navigate/dir1
     4  ~/navigate

Dodatkową wskazówką jest utworzenie aliasu dla dirs -v.

Na przykład:

# In ~/.bashrc
alias dirs="dirs -v"

28
Możesz wyczyścić stosdirs -c
Jun Murakami,

19
+1 za podanie praktycznych przykładów. Łatwo jest zobaczyć, co robią pushd / popd ze strony podręcznika man, ale katalogi i cd ~ # na początku nie są oczywiste.
Scribblemacher

zamiast tego możesz również użyć rozwiązania typu fasd dla tego rodzaju przepływu pracy
WuTheFWasThat

więc lepiej jest w przypadku przejściowego użycia niż ustawienie CDPATH?
rfabbri

2
@ Jun, jest „mkdir dir {1,2,3}”, aby utworzyć 3 katalogi za jednym razem.
Bulat M.

39

Jednym prostym przypadkiem użycia stosu plików katalogów, czego nie można zrobić za pomocą samego dysku CD, jest:

pushd .dodaje bieżący katalog XX do dirsstosu. Następnie możesz poruszać się za pomocą cd, a aby powrócić do XX, po prostu rób to popdniezależnie od tego, jak „daleko” jesteś w drzewie katalogów (możesz przeskakiwać wiele poziomów, na boki itp.). Szczególnie przydatne w skryptach bash.


2
Myślę, że z tej funkcji najczęściej korzystam. Ponieważ pushd/ popdpraca niezależna od cd, możesz użyć ich jako bardziej stabilnej zakładki niż cd -.
Gordon Bean,

dla mnie to nie jest prawda. Za każdym razem, gdy używam cd, mój stos zmienia się.
Harendra Singh,

och, to było korzystanie z zsh, kiedy zmieniam się na bash, to działa dobrze
Harendra Singh

4
To jedyna merytoryczna odpowiedź w odniesieniu do porównania z cd -, IMO. Co do tego, czy pushd foo; <losowa zmiana katalogu>; popd jest bardziej opłacalny niż a = foo; cd $ a; <losowa zmiana katalogu>; cd $ a ... W przypadku skryptów widzę niewielką wygodę syntaktyczną w pierwszej (pushd), ale ogromną poprawę przejrzystości w drugiej ([wyraźne] zmienne!). Jeśli chodzi o sesję interaktywną, myślę, że po prostu założyłem, że moja hierarchia katalogów jest odpowiednio zorganizowana, a jeśli się zgubię, po prostu cd ~ / back / to / oczywistość / ścieżka.
Jan Kyu Peblik,

9

pushdi popdpozwala manipulować katalogami na stosie.

Kiedy jesteś pushdkatalogiem, umieszczasz bieżący katalog na stosie i zmieniasz katalog na katalog określony jako parametr.

popd pozwoli ci wrócić do katalogu na stosie.

Jeśli powtórzysz, przejście do katalogu zostanie zachowane i będziesz mógł wrócić do zapisanych katalogów w odwrotnej kolejności niż te, w których je zapisałeś.


6

dla bash , w zasadzie: zamiast korzystać z cd można pushdzmienić katalogi, z praktycznym zastosowaniem: historia odwiedzanych katalogów jest zapisywana (poprawnie: ułożona w stos) i można przełączać się między nimi

pushd /home; pushd /var; pushd log

Aby zobaczyć użycie stosu dirsi ułatwić nawigację (aby uzyskać numery „wpisów stosu”, użyj:

dirs -v

Wynik:

me@myhost:/home$ dirs -v
 0  /home
 1  /var
 2  /tmp

Teraz wykorzystać te numery ze cdi ~tak:

cd ~1

Ale te liczby są teraz przestawiane i pozycja „0” ulegnie zmianie, więc wystarczy pushddwa razy katalog do najwyższej pozycji (lub użyć manekina na pozycji 0), np .:

me@myhost:/home$ dirs -v
 0  /home
 1  /home
 2  /var
 3  /tmp

teraz 1..3 utrzyma pozycję

(aby zwolnić bieżący katalog ze stosu / usunąć go z historii popd)


5

Jednym praktycznym zastosowaniem, które znalazłem, jest przełączanie się między katalogami za pomocą pushd i popd.

Załóżmy, że mamy dwa katalogi dir1 i dir2, a ja muszę ciągle się między nimi przełączać z jakiegoś powodu xyz.

Obecnie jestem w somedir, który ma dwa katalogi dir1i dir2:

alcohol@alcohol-machine:~/somedir$ ls
dir1  dir2
alcohol@alcohol-machine:~/somedir$ 

Teraz przełączam się na dir1

alcohol@alcohol-machine:~/somedir$ cd dir1
alcohol@alcohol-machine:~/somedir/dir1$ pwd
/home/alcohol/somedir/dir1

Teraz dodam dir1do stosu i przejdę dodir2

alcohol@alcohol-machine:~/somedir/dir1$ pushd /home/alcohol/somedir/dir2
~/somedir/dir2 ~/somedir/dir1
alcohol@alcohol-machine:~/somedir/dir2$

Jak widać, teraz mam dir2i dir1na stosie, a obecnie jestem w grze dir2.

Teraz, aby przełączyć się z powrotem dir1, uruchomię pushd || popd.

alcohol@alcohol-machine:~/somedir/dir2$ pushd || popd
~/somedir/dir1 ~/somedir/dir2
alcohol@alcohol-machine:~/somedir/dir1$ 

Voila, jestem w katalogu 1 i mam katalog 1 i katalog 2 na stosie. Aby ponownie przełączyć na katalog 2, uruchom ponowniepushd || popd

alcohol@alcohol-machine:~/somedir/dir2$ pushd || popd
~/somedir/dir1 ~/somedir/dir2
alcohol@alcohol-machine:~/somedir/dir1$ 

To prosty sposób przełączania się między katalogami. Teraz możesz wiedzieć, dlaczego muszę przełączać się między katalogami? Cóż, jednym z przypadków użycia jest to, że kiedy pracuję nad aplikacją internetową, mam plik make w jednym katalogu, a pliki dziennika w innym katalogu. Często podczas debugowania aplikacji muszę przełączać się między katalogiem dziennika, aby sprawdzić najnowsze dzienniki, a następnie wrócić do katalogu make, aby wprowadzić zmiany i zbudować aplikację.


11
(1) Pytanie pyta: „Jakie są zalety pushdi popdponad cd -?” Wyraźnie nie odpowiedziałeś na to pytanie, ponieważ dokładnie opisujesz, co cd -robi. (2) Jaki jest sens powiedzenia pushd || popd? Tak, wiem, że cmdA || cmdBto oznacza ucieczkę, cmdAa jeśli się nie powiedzie, wtedy biegnij cmdB. Pytam, co dobrego robi w tym kontekście.  pushdbez argumentów oznacza „zamień dwa górne elementy na stosie katalogów”; kończy się niepowodzeniem, jeśli bieżący katalog jest jedynym elementem na stosie katalogów. W takim przypadku popdrównież się nie powiedzie.
G-Man,

3
Nie mogę uwierzyć, że nikt cię nie ocenił! Ratownik! Co za wspaniały hack. Dzięki. Przełączanie, moim zdaniem, w przypadku użycia do pushdi popd.
Sonny,

3
Istnieją dwa różne sposoby, które wymagają znacznie mniej pisania niż pushd || popdw celu przełączania się między katalogami: pushdbez argumentów robi to tylko. cd -jawnie istnieje wyłącznie w celu powrotu do ostatniego katalogu. Dodatkowo, pytanie dotyczyło przewagi pushdnad cd -, podczas gdy ta odpowiedź wyraźnie ma tylko wadę: więcej pisania.
Benjamin Riggs,

W bash, bez argumentów, pushd wymienia dwa górne katalogi i zwraca 0. Dlaczego potrzebujesz || popdprzełącznika? Proszę wytłumacz. (Czy to nie wystarczy?)
Johnny Wong,

@ Sonny Wystarczy użyć, cd -aby przełączać się między dwoma katalogami. Dodatkowo cdbez żadnych argumentów wraca do twojego katalogu domowego.
Steve,

2

Mówiąc najprościej - gdy trzeba nawigować między więcej niż 2 katalogami, zwykle kilka razy tam iz powrotem, ponieważ cd -po prostu nie da się tego zrobić za pomocą niczego poza 2 folderami.

Na przykład, zamiast na przykład wymyślać poprzednie długie ścieżki, patrząc na historię bufora lub wypełnianie długich ścieżek tabulatorami, po prostu układasz ważne w górę i, jeśli to konieczne, wygodnie do nich przechodzisz według ich liczby. Obracanie między złożonymi strukturami katalogów i długimi ścieżkami staje się płynne i szybkie.

Wbudowane funkcje pozwalają również na zmianę kolejności stosu lub wyskakiwanie katalogów, których już nie potrzebujesz, zapewniając elastyczność w przepływie pracy.

Układanie katalogów może być również stosowane w skryptach podobnie do operacji obejmujących kilka katalogów.


1

Użycie dirs / popd / pushd uznałem za nieco niewygodne. Wymyśliłem swoje osobiste rozwiązanie w tcsh, dodając następujący kod do .alias

  foreach b (. , - 0 1 2 3 4 5 6 7 8 9 )
    alias p$b       'set a=`pwd`; echo $a >! ~/.mydir'$b
    alias cd$b      'cd "`cat ~/.mydir'$b'`"'
    alias del$b     'rm -v ~/.mydir'$b
    alias home$b    'set a="~"; echo $a >! ~/.mydir'$b
  end
    alias cdl       'grep / ~/.mydir*'

w ten sposób aliasowałem na przykład „p”. aby zapisać bieżący działający katalog do pliku ~ / .mydir. i „cd”. aby odzyskać ten katalog, kiedykolwiek i gdziekolwiek chcę. „del.” usuwa odpowiedni plik; "Dom." ustawia katalog na katalog domowy (odpowiednik cd; p.); „cdl” wyświetla listę zapisanych katalogów. Pamiętaj, że jeśli używasz ~ / Dropbox / .mydir $ b (lub innej usługi w chmurze, takiej jak np. OwnCloud) zamiast ~ / .mydir $ b, możesz w inteligentny sposób korzystać z preferowanych katalogów na różnych kontach i komputerach.


0

Używam go w ten sposób w moim bash_profile i .bashrc w ten sposób

vi .bash_profile
alias dirs="dirs -v"
source d.sh
:wq

vi .bashrc
alias dirs="dirs -v"
:wq

vi d.sh
pushd ~/Documents/GIT/seiso-data
pushd ~/Documents/GIT/ewe/EosRegistry
pushd ~/Documents/GIT_LODGING/site-cookbooks
pushd ~/Documents/CHEF_LODGING
pushd  .
:wq

pomaga mi przeskakiwać między katalogami do ostatnio używanych w moim terminalu. :-) Mam nadzieję, że to pomaga w użyciu pushd raczej popd i używam cd ~ stackednumber


0

Używanie cdi cd -pozwala przełączać się między tylko dwoma ostatnio używanymi katalogami. Rozmiar „zestawu roboczego katalogu” wynosi dwa.

Za pomocą pushdmożesz przechowywać dowolnie dużą liczbę katalogów w zestawie roboczym.

Używam pushdraczej czasu niż cd. Po zbudowaniu stosu aktywnych katalogów pushd directory_namemożesz przeskakiwać między nimi przez cały dzień pushd ~#.

pushd dir1
pushd ../dir2
pushd /full/path/to/dir3

# There are now three directories in the stack.

pushd ~3
pushd ~2

# The same three directories are still on the stack, 
# just in a different order.

Używam popdrzadko, tylko wtedy, gdy chcę usunąć katalog ze stosu, gdy wiem, że skończyłem używać tego katalogu.

Przejdź do katalogu i usuń go ze stosu:

popd ~2

Pozostań w bieżącym katalogu i usuń inny katalog ze stosu:

popd +2

W efekcie powstaje styl pracy podobny do otwierania wielu okien lub kart terminali (po jednym dla każdego katalogu, w którym aktywnie pracujesz), ale wszystko w jednym terminalu. Oszczędza to ekran nieruchomości, a ponieważ ścieżki katalogowe są dostępne w jednej powłoce, możesz wykonywać następujące czynności:

  • kopiuj pliki między katalogami, z którymi obecnie pracujesz
  • przeglądaj lub edytuj pliki w innym katalogu, nie przechodząc do niego

Przykłady:

cp ~2/myfile.txt ~4
less ~2/myfile.txt

W tcsh(ale nie bash) możesz nawet zapisać stos katalogów do pliku i przywrócić go później.

Zapisać:

dirs -S ~/dirstack

Przywracać:

dirs -L ~/dirstack

W przeciwnym razie po prostu zamień ~w bashprzykładach na, =aby użyć w tcsh.

pushd =2
popd =4
popd +1

0

Pushd / popd jest tak prostą koncepcją, której zrozumienie zajęło mi trochę czasu, ponieważ ludzie zwykle uczą go, definiując te polecenia jako polecenia „manipulujące stosem katalogów”, co moim zdaniem jest mylące.

Patrzę na to w inny sposób:

pushd [nazwa_folderu] - przeniesie cd do [nazwa_folderu] i udokumentuje miejsce docelowe, którym jest [nazwa_folderu] na stosie katalogów, podczas gdy najwyższy katalog na stosie będzie zawsze bieżącym katalogiem, w którym się znajdujesz

popd - najpierw przeniesie cię do rekordu katalogu znajdującego się na szczycie stosu, a następnie usunie go ze stosu

dirs - wydrukuje stos dir (może być traktowany jako dir Db, gdzie pozycja skrajnie lewa to katalog bieżący (góra stosu)

Tak więc 2 najpopularniejsze przypadki użycia to:

Przypadek użycia 1: Nawigacja za pomocą pushd i popd

root@mypc:/main/$ ls
dir1  dir2  dir3  dir4

root@mypc:/main/$ dirs   # prints the current stack
/main

root@mypc:/main/$ pushd dir1    # Will cd to dir1 and document dir1 in dir stack, stack is now:
/main/dir1 /main 
root@mypc:/main/dir1$    # I am now in /main/dir1

root@mypc:/main/dir1$    # Now let's go wild and document whatever I want
root@mypc:/main/dir1$ pushd ../dir2 
root@mypc:/main/dir2$     # Woo I am in /main/dir2
root@mypc:/main/dir2$ pushd ../dir3 
root@mypc:/main/dir3$     # Woo I am in /main/dir3
root@mypc:/main/dir3$ pushd ../dir4 
root@mypc:/main/dir4$     # Woo I am in /main/dir4
root@mypc:/main/dir4$ dirs   # Now dir stack is:
/main/dir4 /main/dir3 /main/dir2 /main/dir1 /main

Powiedzmy, że zrobiłem powyższe, ponieważ chciałbym wrócić do tych folderów, które udokumentowałem!

Zauważ, że jeśli ręcznie cd, wpłynę na górny wpis stosu katalogu (który zawsze jest bieżącym katalogiem)

root@mypc:/main/dir4$ cd ..   # Now dir stack is:
# (note that /main appear in the leftmost as well which is the top of the stack)
/main /main/dir3 /main/dir2 /main/dir1 /main
root@mypc:/main$ 

Przejdźmy teraz do tyłu:

root@mypc:/main$ popd
root@mypc:/main$     # Still in /main since it was at the top of the dir stack
root@mypc:/main$ dirs    # Stack is now:
/main/dir3 /main/dir2 /main/dir1 /main

root@mypc:/main$ popd
root@mypc:/main/dir3$ popd    # Woo in dir3 now, about to navigate to dir2
root@mypc:/main/dir2$ popd    # Woo in dir2, about to navigate to dir1
root@mypc:/main/dir1$ dirs    # Stack is now:
/main

Ponownie mogę udokumentować dowolny katalog, a następnie ręcznie przejść do innego katalogu, dzięki czemu będę mógł łatwo wrócić do udokumentowanego katalogu, który wstawiłem do stosu.

Przypadek użycia 2: Nawigacja za pomocą numerycznego indeksu stosu

Powiedzmy, że pchnąłem za pomocą pushd dir4 dir3 dir2 dir1, teraz uruchomione dir -v pokaże:

root@mypc:/main$ dirs -v
 0  /main/dir1  (this is the current dir you are in always)
 1  /main/dir2
 2  /main/dir3
 3  /main/dir4

Teraz możesz wykonać dowolną operację Linuksa, która obejmuje katalogi za pomocą indeksu stosu:

root@mypc:/main$ cp ~2/temp.txt ~3/new_temp.txt    # this will run in the background, something like:
# cp /main/dir2/temp.txt  /main/dir3/new_temp.txt

Możesz nawet usunąć konkretny wpis ze stosu katalogów:

root@mypc:/main$ popd ~4

Mam nadzieję, że użycie słów „dokumentowanie” lub pomyśl o stosie dir jako pewnego rodzaju Db upraszcza tę koncepcję!

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.