别名cd推送-这是一个好主意吗?


35

使用以下别名是否是一个好主意:

cd() {
    pushd $1;
}

猛击?

我认为这将非常有用,因为我可以使用一系列popds而不是cd -一次。

在任何情况下这可能是一个问题吗?


2
我知道在zsh中有一个设置可以做到这一点。不知道是什么。是否有必要做一个功能而不是仅仅做一个alias cd=pushd
法尔玛里

2
我将别名放在该函数之上。
alesplin

1
为什么不给新名称起别名呢?怎么pd样 您是系统的唯一用户和管理员吗?
凯文·坎图,2010年

3
@Falmarri zsh选项是autopushd
Michael Mrozek

1
严格来说,这是一个函数,而不是别名(但更好)。
Tripleee

Answers:


39

就个人而言,我将这些放在bashrc中,并一直使用它们:

pushd()
{
  if [ $# -eq 0 ]; then
    DIR="${HOME}"
  else
    DIR="$1"
  fi

  builtin pushd "${DIR}" > /dev/null
  echo -n "DIRSTACK: "
  dirs
}

pushd_builtin()
{
  builtin pushd > /dev/null
  echo -n "DIRSTACK: "
  dirs
}

popd()
{
  builtin popd > /dev/null
  echo -n "DIRSTACK: "
  dirs
}

alias cd='pushd'
alias back='popd'
alias flip='pushd_builtin'

然后,您可以像浏览器一样在命令行上浏览。cd更改目录。back转到您之前使用的目录cd。并且flip将在当前目录和先前目录之间移动,而不会从目录堆栈中弹出它们。总的来说,它运作良好。

我知道的唯一真正的问题是,它是我完全习惯但在其他任何人的机器上都不存在的一组命令。因此,如果我不得不使用别人的机器,那可能会令人沮丧。如果您习惯于直接使用pushdpopd直接使用,那么您就不会有这个问题。而且,即使您只是别名cdput not popd,也不会出现back不存在的问题,cd但仍然会遇到无法在其他计算机上实现预期的问题。

但是,我要指出的是,您的特定实现cd并不完全正常cd,正常情况cd下它会进入您的主目录,但您的不是。我在这里使用的版本没有这个问题。我的作品还附加DIRSTACKdirs版画的正面,但这更多的是个人喜好,而不是任何事情。

因此,正如我所说,我一直在使用这些别名,而对它们没有任何问题。只是不得不使用另一台机器然后发现它们不在那里可能有点令人沮丧(这不足为奇,但是它们是您经常使用而不会考虑它们的那些东西之一) ,因此让它们不像您习惯的那样工作仍然令人惊讶)。


极好的建议!Vi / Vimperator用户可以配置<C-o>popd获得真实的体验。
unperson325680 2011年

1
@progo您能解释一下如何通过目录堆栈弹出来翻转目​​录吗?
乔纳森。

习惯了zsh配置后,就缺少了:(1)对目录堆栈中的项进行重复数据删除,以及(2)直接将CD索引到目录中具有其索引的项的方法。我认为我可以轻松地编写包装程序来实现这些功能……不幸的是,似乎不允许修改bash的DIRSTACK,因此可能不得不保留重复项。
史蒂文·卢

您能添加清除清除目录吗?
Pasupathi Rajamanickam

7

这不是问题的直接答案,但是我爱上了4DOS中的目录历史窗口。如此之多,以至于我为Linux(和Cygwin)编写了自己的版本。我从来没有使它成为易于安装的实用程序,但是,如果您了解Bash提示的方式,那么运行它就不会那么困难。您的问题启发了我将其放入Git 仓库中,并将其上传到GitHub:dirhistory

基本上,它是一个守护程序,它从所有外壳程序中收集目录更改,而Cdk程序则显示历史记录,并允许您选择要切换到的任何目录(因此,您不仅限于堆栈)。我发现它确实很有用,并且将其绑定到Ctrl-PageUp,就像4DOS一样。(我什至修补了PuTTY,以便它将Ctrl-PageUp发送到Bash。)


0

对我而言,push / popd / dirs几乎是有用的,但缺乏。因此,我围绕这些对象创建了一个“包装器”,称为“ navd”,实际上是由20个别名组成的。(实际上,其中一个是函数。)下面是代码,但是这里首先是一个简短的说明。(关于“ navd”和在其他人的机器上工作的一件好事:有一种“无安装”形式运行它:作为一种安装选项,您可以简单地在bash提示符处粘贴实现“ navd”的命令,并且在该机器navd的bash会话持续时间内,文件系统的占用空间为零,但这是临时安装,请将这些命令放在.bashrc中以进行“真实”安装,课程。)

特征:

navd <path>;   -- will make that path the current dir AND will add it to the stack
                         AS A BONUS: If a relative path is used, this command is added to history
                         with an absolute path instead. This improves navigation even when only
                         using history ... because very often relative-path commands in history
                         are useless if the command changes the current directory. (After all, you
                         would have to be in the directory the command was originally issued
                         from in order for such a command to work correctly.)
navd           -- shows the stack, with index numbers for convenience
navd0          -- makes the first entry on the stack (read left-to-right) **the current dir**
navd1          -- makes the second entry on the stack (read left-to-right) **the current dir**
.
.
.
navd9          -- makes the tenth entry on the stack (read left-to-right) **the current dir**
navd-1         -- makes the first entry on the stack WHEN READ RIGHT-to-LEFT(!) **the current dir**
.                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
.
.
navd-9         -- makes the 9th entry on the stack WHEN READ RIGHT-to-LEFT(!) **the current dir**

十九个navd <N>命令中的任何一个都旋转堆栈,以便成为当前目录的目录现在显示在堆栈的最前面。正数<N>会找到一个从左开始计数的目录,索引从零开始。负<N>值会找到一个从RIGHT开始计数的目录,索引从-1开始。(这遵循了如何在Java和其他语言中使用数组索引的约定。)

注意:任何“ navd”命令都显示“ pushd”和“ dirs”使用的同一堆栈-但不显示“ dirs”将显示的最左边的条目而显示它 (因为该条目实际上不在堆栈上-当前目录 如果输入cd命令,则最左边的条目带有“ dirs”(目录)。(“唯<路径>”命令不影响navd的任何行为,但它肯定会影响行为的PUSHD /目录/ POPD也...我爱用。“CD - ”走“回” 一旦到我刚刚离开的目录,“ cd-”也不影响navd的行为。)

奖励:还有19个别名不会旋转堆栈,而只是将dir更改为堆栈上指示的位置。

 nav0 ... nav9   and   nav-1  ... nav-9

第二个好处:“ navh”显示历史记录中的navd <path>命令,可轻松地使用cut-n-paste加载堆栈。(即使每个条目都在历史记录中多次列出,每个列表也仅列出一次,并且对列表进行排序。此外,可以将条目放在$ HOME / .navhignore文件中,以防止这些确切的条目出现在navh列表上。)

 navh

三种主要行为:

  1. 如果清除堆栈并重复执行特定的“ navd <path>”命令,则该路径将进入堆栈。这就是我想要和期望的...但是push并没有做到这一点-它会将您正在导航的当前目录放在堆栈上-因此当您重复执行该命令时,堆栈上的效果是可变的(感觉不可预测) 。

  2. “ navd <path>”不会将同一路径两次放入堆栈。

  3. 即使输入了相对路径,“ navd <路径>” 也会使用绝对路径将其自身放入命令历史记录中。

对我而言,所描述的后三种行为使使用历史记录中的“ navd <path>”命令比使用历史记录中的“ pushd <path>”更为有用。我真的可以重用历史去地方。当我这样做时,我不会“破坏”我的筹码量。

如果可以并且希望将自己的大脑包起来,则可以在使用navd和pushd / dirs / popd之间切换。两者使用相同的堆栈;只是风格不同。例如,使用“ popd”从“ navd”堆栈中删除内容,或使用“ dirs -c”清除navd堆栈。

将push / dirs / popd认为是“我如何追溯我的脚步?”。
将navd视为“我如何保留一组喜欢的目录,并在它们之间轻松切换?”。

将以下内容粘贴到终端窗口中,您可以在该终端会话期间立即开始使用navd。这是此功能的所有代码。

# Add 1 function and many related aliases for something like "pushd", called "navd". http://unix.stackexchange.com/a/229161
# Think of pushd/dirs/popd as "how do I retrace my steps?".
# Think of navd as "how do I hold on to a set of favorite directories, and easily switch between them?".
# Pseudo-code to explain each part of the "navd" bash function just below:
#              If no arguments to the 'navd' command:
#                  If stack has entries, then print the stack one-line-per-dir with each line numbered.
#                  Else, if stack is empty, automatically run the equivalent of the navh command.
#              Else (there **are** arguments to the 'navd' command):
#                  If arg is '--help' or '/?' then show help.
#                  Else    (arg is assumed to be a path to a directory)
#                      Remember the directory we are starting at
#                      Change to dir given as argument (the "arg-dir"), and do a few chores:
#                      Do not use arg-dir literally ... instead, magically put the **absolute** path we arrived at into history.
#                      Set a flag if the arg-dir is already in the stack.
#                      If the flag is set then just show the stack (on one line), else ADD to stack, ROTATE to end-of-stack, and show the stack.
#                      Change to dir we started at and then back to the arg-dir. This allows "cd -" to go back to dir we started at.
#                  End-If
#              End-If
navd () {
    if [[ $1 == '' ]]; then                             #--no arguments to the 'navd' command
        if dirs +1 >/dev/null 2>&1; then                #------stack has entries
            dirs -p | perl -ne 'print (-1+$cn++); print "$_"' | grep -v "^-1";
        else                                            #------stack is empty
            echo "The navd stack is empty. Now running 'navh' in case that's helpful. navd --help works."
            if [[ ! -f $HOME/.navhignore ]]; then echo -n ''>>$HOME/.navhignore;fi;diff --new-line-format="" --unchanged-line-format="" <(history | perl -ne "if (m/^\s*\d+\s+navd [\"~.\/]/) {s/^\s*\d+\s+/  /;s/\/$//;print}" | sort -u) <(cat $HOME/.navhignore | sort -u);echo "cat $HOME/.navhignore # (Has "`grep -c . <(sort -u $HOME/.navhignore)`" unique lines.)"
        fi
    else                                                #--(there **are** arguments to the 'navd' command)
        if [[ $1 == '--help' || $1 == '/?' ]]; then     #------arg is '--help' or '/?'
            echo "The 'navd' functionality is nothing but one bash function and a set of aliases."
            echo "It offers a different style of handy directory navigation than pushd/popd."
            echo "It uses the same 'stack' as pushd. Look in the .bashrc file for details."
            echo "    (Think of pushd/dirs/popd as 'how do I retrace my steps?'."
            echo "     Think of navd as 'how do I remember a set of favorite directories,"
            echo "     and easily switch between them?'.)"
            echo "As of 10/2015, this link has more info: http://unix.stackexchange.com/a/229161"
            echo "Here is the set of navd-related aliases. None need any parameter:"
            alias | grep 'alias nav' | cut -d= -f1 | grep -v '-' | grep -v 'navh'
            alias | grep 'alias nav' | cut -d= -f1 | grep '-'
            echo "alias navh  # The 'navh' alias has nothing to display until a 'navd <path>' is run. Short for nav-history."
            echo "---- To get started, simpy type navd followed by your favorite path. ----"
            echo "---- navd with no param shows stack. nav0 navigates to first on stack. ----"
        else                                            #------(arg is assumed to be a path to a directory)
            mypwd="$PWD"
            cd "$1" >/dev/null;
            history -s `echo "$PWD" | perl -pe 's/$ENV{'HOME'}/~/;s/ /\\\\ /g;s/^/navd /'`
            myflag=`dirs -p | perl -pe 's/\n/:/' | perl -ne '@a=split(":");$pwd=shift(@a);$flag=0;foreach (@a) {if ($_ eq $pwd) {$flag=1}};print $flag'`
            if [[ $myflag == 1 ]]; then dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"; else pushd .>/dev/null; pushd +1>/dev/null; dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"; fi
            cd "$mypwd"; cd "`dirs -l -0`"
        fi
    fi
};
# Aliases for navigating and rotating the "pushd" stack in the style of "navd":
alias navd0='cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"' # "-l" is dash-L, and expands "~" to denote the home dir. Needed inside back-ticks.
alias navd1='cd "`dirs -l +1`";pushd -n +1;cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd2='myd=$PWD;cd "`dirs -l +1`";for i in {1..2};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd3='myd=$PWD;cd "`dirs -l +1`";for i in {1..3};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd4='myd=$PWD;cd "`dirs -l +1`";for i in {1..4};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd5='myd=$PWD;cd "`dirs -l +1`";for i in {1..5};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd6='myd=$PWD;cd "`dirs -l +1`";for i in {1..6};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd7='myd=$PWD;cd "`dirs -l +1`";for i in {1..7};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd8='myd=$PWD;cd "`dirs -l +1`";for i in {1..8};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd9='myd=$PWD;cd "`dirs -l +1`";for i in {1..9};do pushd -n +1>/dev/null;cd "`dirs -l +1`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-1='cd "`dirs -l -0`";pushd -n -0>/dev/null; dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-2='myd=$PWD;cd "`dirs -l -0`";pushd -n -0>/dev/null;cd "`dirs -l -0`";pushd -n -0>/dev/null;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-3='myd=$PWD;cd "`dirs -l -0`";for i in {1..3};do pushd -n -0>/dev/null;cd "`dirs -l -0`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-4='myd=$PWD;cd "`dirs -l -0`";for i in {1..4};do pushd -n -0>/dev/null;cd "`dirs -l -0`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-5='myd=$PWD;cd "`dirs -l -0`";for i in {1..5};do pushd -n -0>/dev/null;cd "`dirs -l -0`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-6='myd=$PWD;cd "`dirs -l -0`";for i in {1..6};do pushd -n -0>/dev/null;cd "`dirs -l -0`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-7='myd=$PWD;cd "`dirs -l -0`";for i in {1..7};do pushd -n -0>/dev/null;cd "`dirs -l -0`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-8='myd=$PWD;cd "`dirs -l -0`";for i in {1..8};do pushd -n -0>/dev/null;cd "`dirs -l -0`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-9='myd=$PWD;cd "`dirs -l -0`";for i in {1..9};do pushd -n -0>/dev/null;cd "`dirs -l -0`";done;cd "$myd";cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
# BONUS commands (beyond the 20). Aliases for navigating but NOT rotating the "navd" stack:
#      Help in remembering: "navd<#>" does more since it both changes the PWD and rotates the stack, whereas "nav<#>" does less
#            (and has one letter less) since "nav<#>" only changes the PWD. Also "navd<#>" acts like the pushd-related command: dirs
#      There is no "nav" command (with no number) so that there will be no conflict if any program called "nav" is used.
alias nav0='cd "`dirs -l +1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav1='cd "`dirs -l +2`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav2='cd "`dirs -l +3`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav3='cd "`dirs -l +4`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav4='cd "`dirs -l +5`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav5='cd "`dirs -l +6`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav6='cd "`dirs -l +7`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav7='cd "`dirs -l +8`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav8='cd "`dirs -l +9`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav9='cd "`dirs -l +10`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-1='cd "`dirs -l -0`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-2='cd "`dirs -l -1`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-3='cd "`dirs -l -2`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-4='cd "`dirs -l -3`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-5='cd "`dirs -l -4`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-6='cd "`dirs -l -5`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-7='cd "`dirs -l -6`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-8='cd "`dirs -l -7`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-9='cd "`dirs -l -8`";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
# BONUS command (beyond the 20). Alias for showing 'history' of all navd commands that add to the stack.
#                Can be used in a new terminal session to quickly add recently used dirs to the navd stack.
alias navh='if [[ ! -f $HOME/.navhignore ]]; then echo -n ''>>$HOME/.navhignore;fi;diff --new-line-format="" --unchanged-line-format="" <(history | perl -ne "if (m/^\s*\d+\s+navd [\"~.\/]/) {s/^\s*\d+\s+/  /;s/\/$//;print}" | sort -u) <(cat $HOME/.navhignore | sort -u);echo "cat $HOME/.navhignore # (Has "`grep -c . <(sort -u $HOME/.navhignore)`" unique lines.)"'
# Note: When 'navd <relative-path>' is used, then by bash-magic the navd command puts 'navd <absolute-path>' into history,
#       instead. This allows the output of "navh" to be useful regardless of the directory that is current when it is run.
#
# BONUS commands (beyond the 20). An even shorter alias for navd. An even shorter alias for navh.
alias nd='navd'
alias nh='if [[ ! -f $HOME/.navhignore ]]; then echo -n "">>$HOME/.navhignore;fi;diff --new-line-format="" --unchanged-line-format="" <(history | perl -ne "if (m/^\s*\d+\s+navd [\"~.\/]/) {s/^\s*\d+\s+/  /;s/\/$//;print}" | sort -u) <(cat $HOME/.navhignore | sort -u);echo "cat $HOME/.navhignore # (Has "`grep -c . <(sort -u $HOME/.navhignore)`" unique lines.)"'

这些别名基于“ bash”命令。要特别注意保持“ cd-”的正常行为。(很多时候,我使用“ cd-”来代替打扰或导航-因为“ cd-”对于返回到您的最后一个“位置”非常方便,或者仅在两个位置之间切换,并且无需安装即可在任何地方使用。)

当然,这些命令可以放入.bashrc文件中,以进行更永久的安装。


1
Dana,您似乎有两个同名的独立帐户。您可以轻松地合并它们
roaima

您每次更改目录时都会启动一个perl解释器吗?不用了,谢谢。
Tripp Kinetics

0

这是您可能想要的另一种解决方案。我在使用@cjm解决方案后编写了此代码。它使用对话框命令从dirs的输出创建ncurses类型菜单。选择一个项目将把该目录带到堆栈的顶部,并放入其中。与历史记录相比,这样做的好处是为每个终端仿真器提供了自己的目录历史记录缓冲区,并且安装起来更加容易。

要安装:将cd别名推入后,安装对话框,然后将以下功能放入您的bashrc中:

dirmenu(){
    dirIter=$(dialog --backtitle 'dirmenu' --clear --cancel-label "Exit" --menu "Please select:" 0 0 0 $(dirs) 3>&2 2>&1 1>&3)
    cmd="builtin cd ~$dirIter"
    eval $cmd
}

我喜欢运行dirs -v更好,然后运行另一个命令来弹出或cd到我想要的目录。对话框菜单也可以通过它的dialogrc高度自定义。

因此,回答您的问题,是的,我认为推入cd的别名是一个好主意。如果至少要定期重新启动计算机以进行更新,则不太可能出现缓冲区溢出问题。尽管我在编写脚本时会小心使用cd;cd在while循环中可能会导致缓冲区溢出问题。我不确定是什么控制了dirs / pushd缓冲区的大小。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.