当使用这两个命令比pushdpopd有优势时,cdcd -的实际用途是什么?

编辑:我正在寻找这两个命令的一些实际使用示例或与目录保持堆栈的原因(当您使用制表符补全,cd -,用于缩短cd ..的别名等时)。

#1 楼

pushdpopddirs是shell内置程序,可让您操纵目录堆栈。这可以用于更改目录,但可以返回到您来自的目录。例如,

以下列目录启动:

$ ls
dir1  dir2  dir3


推到dir1

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


dirs命令确认我们现在在堆栈上有2个目录。 dir1和原始目录somedir。注意:我们的“当前”目录是~/somedir/dir1

推送到../ dir3(因为我们现在位于dir1中)

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


dirs显示我们现在在堆栈中有3个目录。 dir3dir1somedir。注意方向。每个新目录都添加到左侧。当我们开始弹出目录时,它们也会从左侧出现。

手动将目录更改为../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


评论


谢谢,我完全理解堆栈的概念以及该命令的工作方式。但是,我正在寻找一些与目录保持堆栈的实际原因(当您具有制表符补全,cd-,用于缩短cd ..的别名等时)。

–先天性
13年5月25日在18:26



我经常在脚本b / c中使用push&popd,它们使我不必记住我来自哪里,我总是可以弹出来从我那里回来。我通常会执行popd> / dev / null 2>&1使其静音。我每天在外壳中使用cd-。本文中还有其他一些节省时间的技巧:thegeekstuff.com/2008/10/…。

–slm♦
13年5月25日在18:31



@Garrett-我无法想象的。

–slm♦
2014年8月22日,1:11

@Garrett @slm因为cd-仅跟踪最后一个目录,我想如果调用一个也在内部更改目录的函数,可能会出现问题。在这种情况下,该函数最终将重置-您的当前目录,而不是您要弹出的目录。推入/弹出是最安全的方法。注意:我尚未检验我的理论。

– Bine Phile
2014年11月10日20:52

为什么在第一个弹出窗口之后不返回〜/ somedir / dir3?

– Ziyuang
16年2月18日在22:03

#2 楼

pushdpopd命令有一个非常有用的用例,可以同时使用多个文件夹。

由于枚举已枚举,因此可以非常轻松地浏览堆栈。
意思是,可以有多个工作期间可以使用的工作文件夹。

请参见下面的简单示例。


首先,让我们创建示例文件夹结构。

    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



其他提示是为dirs -v创建一些别名。

例如:

    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 -c清除堆栈

–村上淳
16 Mar 17 '16 at 13:18

+1实际给出一些实际例子。很容易从手册页中看到push / popd的功能,但是起初,dirs和cd〜#并不明显。

– Scribblemacher
16年4月12日在15:50

您也可以使用fasd这样的解决方案来代替这种工作流程

–WuTheFWasThat
16年6月15日在23:39

@Jun,有一个“ mkdir dir {1,2,3}”,可以一口气创建3个目录。

– Bulat M.
18年2月19日在7:38

@JunMurakami这让我很开心! 2020年快乐!

– David West
1月17日在16:22

#3 楼

使用dirs堆栈的一个简单用例是仅用cd不能完成的操作:

pushd .将当前目录XX添加到dirs堆栈。然后,您可以使用cd来回移动,而返回XX则只需执行popd,而不管您在目录树中有多远(可以跳过多个级别,横向等等)。在bash脚本中特别有用。

评论


我认为这是我最常使用的功能。由于推入/弹出操作独立于cd,因此您可以将它们用作比cd-更稳定的书签。

–戈登·宾
16年8月17日在15:31

对我来说这不是真的。每次我使用cd时,我的堆栈都会更改。

– Harendra Singh
17年4月4日在4:48

哦,那是使用zsh的原因,当我更改为bash时,它可以正常工作

– Harendra Singh
17年4月4日在5:07

与cd-IMO相比,这是唯一的实质性答案。至于是否推送foo; <更改随机目录>; popd比a = foo更值得; cd $ a; <更改随机目录>; cd $ a ...对于脚本,我可以看到前者(推送)在语法上有一点点方便,但是后者([显式]变量!)的清晰度有了很大的提高。对于交互式会话,我想我只是假设我的目录层次结构首先是正确组织的,如果我迷路了,则只需使用cd〜/ back / to / obvious / path。

– Jan Kyu Peblik
17年6月15日在18:27



@HarendraSingh您没有碰巧设置了AUTO_PUSHD吗?它将使cd表现得像被按下一样,取消设置它,您将回到“正常行为”。

–马格努斯
19/12/25在9:28

#4 楼

pushdpopd允许您操作堆栈上的目录。

pushd目录时,将当前目录放在堆栈上,并将目录更改为指定为参数的目录。

popd将允许您返回到堆栈上的目录。

如果重复,将遍历目录遍历,并且可以从与保存它们相反的顺序返回到保存的目录。

#5 楼

对于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

#6 楼

push / popd是一个简单的概念,使我花了一段时间才理解,因为人们倾向于通过将这些命令定义为“操纵目录栈”的命令来教它,我认为这非常令人困惑。

我以另一种方式看待它:

推[folder_name]-将cd到[folder_name],并在目录堆栈中记录目标位置,即[folder_name],
位于顶层目录中堆栈中的目录始终是您当前所在的目录。

popd-首先将您CD放入堆栈顶部的目录记录中,然后删除文档(将其从目录堆栈中删除)

dirs-将打印dir堆栈(可以视为dir Db,其中最左边的条目是当前目录(堆栈的顶部)

所以2种最受欢迎用例是:

用例1:使用push和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,则会影响顶部目录堆栈条目(始终是当前目录)。

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


我可以再次记录所需的任何目录,然后手动导航至另一个目录,这样我便可以轻松地返回记录的目录I

用例2:使用数字堆栈索引进行导航

假设我使用push dir4 dir3 dir2 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


希望使用“记录”一词或将目录堆栈作为某种Db来简化概念!

#7 楼

简而言之-当您需要在两个以上的目录之间进行导航时(通常是来回几次),因为cd -不会用超过2个文件夹的任何内容进行剪切。

因此,例如通过查看缓冲区的历史记录或通过制表符完成一条长路径来尝试重新找到以前的长路径,您只需将重要的那些堆积起来,如果需要,您可以仅通过它们的编号方便​​地移至它们。在复杂的目录结构和长路径之间进行旋转变得轻而易举。

内置函数还允许您重新排序堆栈或弹出不再需要的目录,从而使工作流程更加灵活。

目录堆栈也可以在脚本中类似地用于跨越多个目录的操作。

#8 楼

我发现使用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*'


中,这样我就可以别名“ p”。将当前工作目录保存到文件〜/ .mydir中。和“ cd”。可以随时随地恢复该目录。
“ del”。删除相应的文件; “家。”将目录设置为主目录(相当于cd; p。); “ cdl”列出了保存的目录。
请注意,如果您使用〜/ Dropbox / .mydir $ b(或任何其他云服务,例如ownCloud)而不是〜/ .mydir $ b,您将获得一种聪明的方法在不同的帐户和机器上使用您喜欢的目录。

#9 楼

使用cdcd -只允许您在两个最近使用的目录之间切换。您的“目录工作集”大小为2。

使用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


否则,只需将~示例中的bash替换为=即可在tcsh中使用。


#10 楼


我在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


它可以帮助我在目录之间跳转到最近使用的目录在我的终端上。 :-)希望它可以帮助您使用push而不是popd我使用cd〜stackednumber