Как мне использовать команды pushd и popd?


332

Каковы практические применения обоих pushdи popdкогда есть преимущество использования этих двух команд над cdи cd -?

РЕДАКТИРОВАТЬ : я ищу некоторые практические примеры использования обеих этих команд или причин для сохранения стека с каталогами (когда у вас есть завершение табуляции cd -, псевдонимы для сокращения cd ..и т. Д.).

Ответы:


304

pushd, popdИ dirsявляются оболочки , которые позволяют встроенные функции вам манипулировать стек каталогов . Это можно использовать для изменения каталогов, но вернитесь в каталог, из которого вы пришли.

Например

запустите со следующими каталогами:

$ ls
dir1  dir2  dir3

Pushd to Dir1

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

dirsКоманда подтверждает, что у нас есть 2 каталога в стеке. dir1и оригинальный каталог somedir.

pushd to ../dir3 (потому что мы сейчас внутри dir1)

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

dirsпоказывает, что у нас есть 3 каталога в стеке сейчас. dir3, dir1и somedir. Обратите внимание на направление. Каждый новый каталог добавляется слева. Когда мы начнем извлекать каталоги, они тоже придут слева.

вручную изменить каталоги на ../dir2

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

Теперь начните выскакивать каталоги

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

Обратите внимание, что мы вернулись обратно dir1.

Поп снова ...

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

И мы вернулись туда, откуда начали somedir.

Может показаться немного запутанным, но заголовок стека - это каталог, в котором вы сейчас находитесь. Следовательно, когда мы вернемся somedir, даже если покажем dirsэто:

$ dirs
~/somedir

Наш стек фактически пуст.

$ popd
bash: popd: directory stack empty

19
Спасибо, я полностью понимаю концепцию стека и как работают эти команды. Однако я ищу некоторые практические причины для сохранения стека с каталогами (когда у вас есть завершение табуляции cd -, псевдонимы для сокращения cd ..и т. Д.).
синтагма

21
Я часто использую pushd& popdв сценариях, потому что они избавляют меня от необходимости помнить, откуда я пришел, я всегда могу просто popdвернуться туда, откуда пришел. Я обычно делаю, popd >/dev/null 2>&1чтобы заставить его замолчать. Я использую CD- каждый день в моей оболочке. В этой статье есть и другие советы по экономии времени: thegeekstuff.com/2008/10/… .
SLM

2
@ Гарретт - ничего такого, что я могу себе представить.
СЛМ

4
@Garrett @slm, поскольку cd -отслеживает только последний каталог, я думаю, что могут возникнуть проблемы, если вы вызовете функцию, которая также меняет каталог внутри. в этом случае функция перестанет сбрасываться - в ваш текущий каталог, а не в каталог, в который вы хотите вернуться. pushd / popd - самый безопасный метод. Примечание: я не проверял свою теорию.
Binary Phile

5
Почему бы не вернуться ~/somedir/dir3после первого popd?
Ziyuang

198

Существует очень полезный вариант использования pushdи popdкоманд для работы с несколькими папками одновременно.

Вы можете перемещаться по стеку очень легко, так как он перечисляется. Это означает, что вы можете иметь несколько рабочих папок в вашем распоряжении во время работы.

Смотрите простой пример ниже.


Сначала давайте создадим пример структуры папок.

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

Затем вы можете добавить все свои папки в стек:

    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

Вы можете посмотреть это:

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

Для безопасной навигации вам нужно добавить последнюю (нулевую) папку дважды, так как она всегда будет переписана:

    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

Теперь вы можете перемещаться по этим папкам и работать со стеком, как с псевдонимами для папок. Я думаю, что следующая часть говорит сама за себя:

    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

Дополнительный совет - создать псевдоним для dirs -v.

Например:

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

28
И вы можете очистить стек поdirs -c
июнь Мураками

19
+1 за фактические примеры. Легко увидеть, что pushd / popd делает со страницы man, но dirs и cd ~ # поначалу не очевидны.
Scribblemacher

вы также можете использовать решение, подобное fasd, для такого рода рабочих процессов
WuTheFWasThat

так что лучше для более временного варианта использования, чем установка CDPATH?
rfabbri

2
@Jun, есть «mkdir dir {1,2,3}» для создания 3 каталогов за один снимок.
Булат М.

39

Один простой пример использования стека dirs, который вы не можете сделать просто cd:

pushd .добавляет текущий каталог XX в dirsстек. После этого вы можете перемещаться с помощью cd, а чтобы вернуться к XX, вы просто делаете это popdнезависимо от того, насколько «далеко» вы находитесь в дереве каталогов (можете перепрыгивать через несколько уровней, в стороны и т. Д.). Особенно полезно в скриптах bash.


2
Я думаю, что это особенность, которой я пользуюсь чаще всего. Поскольку pushd/ popdработать независимо от cd, вы можете использовать их в качестве более стабильной закладки, чем cd -.
Гордон Бин

для меня это неправда. Каждый раз, когда я использую CD, мой стек меняется.
Харендра Сингх,

о, это было из-за того, что я использовал zsh, когда я
перехожу

4
Это единственный существенный ответ по сравнению с CD - IMO. Что касается того, является ли pushd foo; <случайное изменение каталога>; popd важнее, чем a = foo; cd $ a; <случайное изменение каталога>; cd $ a ... Для сценариев я вижу крошечное синтаксическое удобство в первом (pushd), но значительное улучшение ясности во втором ([явные] переменные!). Для интерактивного сеанса, я думаю, я бы просто предположил, что моя иерархия каталогов организована должным образом, и если я заблудился, просто cd ~ / back / to / Очевидный / путь.
Ян Кью Пеблик

9

pushdи popdпозволяют вам манипулировать каталогами в стеке.

Когда вы pushdкаталог, вы помещаете текущий каталог в стек и меняете каталог на каталог, указанный в качестве параметра.

popd позволит вам вернуться в каталог в стеке.

Если вы повторитесь, обратный путь в каталогах будет сохранен, и вы сможете вернуться в сохраненные каталоги в порядке, обратном тому, в котором вы их сохранили.


6

для bash , в основном: вместо использования cd можно использовать pushdдля изменения каталогов, с практическим использованием: история посещенных каталогов сохраняется (правильно: сложено) и можно переключаться между ними

pushd /home; pushd /var; pushd log

Чтобы увидеть использование стека dirsи для более удобной навигации (чтобы получить номера «записей стека», используйте:

dirs -v

Выход:

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

Теперь используйте эти числа с cdи ~как:

cd ~1

Но эти числа теперь переставлены, и позиция «0» изменится, поэтому просто pushdпоместите каталог в верхнюю позицию дважды (или используйте пустышку в позиции 0), например:

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

Теперь 1..3 сохранит там свои позиции

(чтобы освободить текущий каталог из стека / удалить его из истории использования popd)


5

Одно практическое применение, которое я нашел, - переключение между каталогами с помощью pushd и popd.

Предположим, у нас есть два каталога dir1 и dir2, и мне нужно постоянно переключаться между ними по какой-то причине xyz.

В настоящее время я нахожусь в Somedir, который имеет две директории dir1и dir2:

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

Теперь я переключаюсь на dir1

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

Теперь я добавлю dir1в стек и переключусь наdir2

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

Как вы видите, у меня сейчас есть dir2и dir1в стеке, и я в настоящее время в dir2.

Теперь, чтобы переключиться обратно dir1, я побегу pushd || popd.

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

Вуаля, я в dir1 и у меня есть dir1 и dir2 в стеке. Чтобы снова переключиться на dir2, запуститеpushd || popd

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

Это простой способ переключения между каталогами. Теперь вы можете что знать, зачем мне переключаться между каталогами? Один из вариантов использования: когда я работаю над веб-приложением, мой make-файл находится в одном каталоге, а мои файлы журналов - в другом. Часто при отладке приложения мне нужно переключаться между каталогами журналов, проверять последние журналы и затем переключаться обратно в каталог make, чтобы внести некоторые изменения и собрать приложение.


11
(1) Вопрос задает вопрос: «Каковы преимущества pushdи popdболее cd -?» Вы явно не ответили на этот вопрос, так как вы описываете именно то, что cd -делает. (2) Какой смысл говорить pushd || popd? Да, я знаю, что cmdA || cmdBзначит «бежать» cmdAи, если не получится, запустить cmdB. Я спрашиваю, что хорошего в этом контексте.  pushdбез аргументов означает «поменять два верхних элемента в стеке каталогов»; это терпит неудачу, если текущий каталог является единственным элементом в стеке каталогов. В этом случае popdтакже не удастся.
G-Man

3
Я не могу поверить, что никто не проголосовал против вас! Спасатель! Какой замечательный хак. Благодарю. Переключение, на мой взгляд, в случае использования для pushdи popd.
Сонни

3
Есть два различных способа, которые требуют гораздо меньшего количества операций по вводу, чем pushd || popdдля переключения между каталогами: pushdбез аргументов делает это. cd -явно существует исключительно для переключения обратно в последний каталог. Кроме того, вопрос задал преимущество pushdболее чем cd -, в то время как этот ответ явно предоставляет только недостаток: больше печатания.
Бенджамин Риггс

В bash, без аргументов, pushd обменивает две верхние директории и возвращает 0. Зачем вам нужно || popdпереключение? Пожалуйста, объясни. (Разве не достаточно толка?)
Джонни Вонг

@Sonny Просто используйте cd -для переключения между двумя каталогами. Дополнительно cdбез аргументов возвращается в ваш домашний каталог.
Стив

2

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

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

Встроенные функции также позволяют вам переупорядочивать стек или извлекать каталоги, которые вам больше не нужны, обеспечивая гибкость в вашем рабочем процессе.

Укладка каталогов также может использоваться в сценариях аналогично для операций, которые охватывают несколько каталогов.


1

Я нашел использование dirs / popd / pushd немного неудобным. Я придумал свое личное решение в tcsh, добавив следующий код в .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*'

таким образом, я псевдоним, например, "р." сохранить текущий рабочий каталог в файл ~ / .mydir. и "компакт-диск" чтобы восстановить этот каталог, когда и где мне нравится. «Дель». удаляет соответствующий файл; "Главная." устанавливает dir в домашний каталог (эквивалентный cd; p.); "cdl" перечисляет, что является сохраненными каталогами. Обратите внимание, что если вы используете ~ / Dropbox / .mydir $ b (или любой другой облачный сервис, например, ownCloud) вместо ~ / .mydir $ b, вы получите умный способ использования предпочитаемых вами каталогов для разных учетных записей и машин.


0

Я использую это в моем bash_profile и .bashrc вот так

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

это помогает мне переключаться между каталогами на самые последние используемые на моем терминале. :-) Надеюсь, это поможет вам использовать pushd, а не popd, я использую cd ~ stackednumber


0

Использование cdи cd -позволяет вам переключаться только между двумя вашими последними использованными каталогами. Размер вашего "рабочего каталога" равен двум.

Используя pushd, вы можете хранить произвольно большое количество каталогов в вашем рабочем наборе.

Я использую pushdбольшую часть времени, а не cd. После того, как вы создали стек активных каталогов pushd directory_name, вы можете переходить между ними весь день 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.

Я использую popdредко, только когда я хочу удалить каталог из стека, когда я знаю, что я использую этот каталог.

Перейдите в каталог и удалите его из стека:

popd ~2

Оставайтесь в текущем каталоге и удалите другой каталог из стека:

popd +2

Вы получаете рабочий стиль, который похож на открытие нескольких окон или вкладок терминала (по одному для каждого каталога, в котором вы активно работаете), но все в одном терминале. Это экономит пространство экрана, плюс, поскольку все пути к каталогам доступны в одной оболочке, вы можете делать такие вещи, как:

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

Примеры:

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

В tcsh(но не bash), вы даже можете сохранить свой стек каталогов в файл и восстановить его позже.

Сохранить:

dirs -S ~/dirstack

Восстановить:

dirs -L ~/dirstack

В противном случае просто замените ~в bashпримерах =на использование в tcsh.

pushd =2
popd =4
popd +1

0

Pushd / popd - это такая простая концепция, которую мне потребовалось некоторое время, чтобы понять, так как люди склонны учить ее, определяя эти команды как команды, которые «манипулируют стеком каталогов», что, на мой взгляд, сбивает с толку.

Я смотрю на это по-другому:

pushd [имя_папки] - перейдет на [имя_папки] и задокументирует пункт назначения, который является [имя_папки] в стеке каталогов, в то время как верхний каталог в стеке всегда будет текущим каталогом, в котором вы находитесь.

popd - сначала перейдет в директорию записи, которая находится на вершине стека, а затем удалит ее из стека.

dirs - будет печатать стек dir (может рассматриваться как dir Db, где самая левая запись - это текущий каталог (вершина стека)

Итак, 2 самых популярных варианта использования:

Вариант использования 1: навигация с использованием pushd и 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

Допустим, я сделал выше, так как я хотел бы вернуться к тем папкам, которые я задокументировал!

Обратите внимание, что если я вручную cd, я буду влиять на запись верхнего стека dir (который всегда является текущим dir)

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$ 

Давайте теперь перейдем назад:

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

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

Вариант использования 2: навигация с использованием числового индекса стека

Допустим, я нажал, используя pushd dir4 dir3 dir2 dir1, теперь запуск dir -v покажет:

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

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

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

Вы даже можете удалить конкретную запись из стека каталогов:

root@mypc:/main$ popd ~4

Надеюсь, что использование слов «документирование» или представление о стеке dir как о некотором Db упрощает эту концепцию!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.