我们有CD的更多历史记录吗?


Answers:


31

您要查找的命令是pushdpopd

您可以查看的实际工作示例pushdpopd来自这里

mkdir /tmp/dir1
mkdir /tmp/dir2
mkdir /tmp/dir3
mkdir /tmp/dir4

cd /tmp/dir1
pushd .

cd /tmp/dir2
pushd .

cd /tmp/dir3
pushd .

cd /tmp/dir4
pushd .

dirs
/tmp/dir4 /tmp/dir4 /tmp/dir3 /tmp/dir2 /tmp/dir1

1
还有$OLDPWD你要来回翻转使用相同的命令两个目录之间的情况下,但我不知道该如何shell特定的配送/内核特定这是。
mechalynx

4
@ivy_lynx OLDPWD在所有POSIX shell中都存在,但是对于这个问题(它已经问到了cd -哪个是它的快捷方式cd "$OLDPWD")提出了疑问,这个问题无用。
吉尔斯(Gillles)“所以-别再作恶了”

2
您使用cd /tmp/dir1; pushd . 而不是仅仅有原因pushd /tmp/dir1吗?
GnP 2014年

@gnp,没有特定原因。它只是从我在答案中提到的链接中提取的。pushd /tmp/dir1应该工作正常。
拉梅什2014年

1
好的,只是选择了我的好奇心。我想建议你使用提高你的答案有一个实际的例子pushdpopd遍历目录树来回。您的答案已经是正确的答案。
GnP 2014年

53

您没有指定要使用的shell,因此可以以此为理由来宣传zsh。

是的,我们的确有更多历史记录cd,即cd -2cd -4等等。非常方便的是cd -TAB,尤其是启用了完成系统和颜色后:

这是我在.zshrc中拥有的:

setopt AUTO_PUSHD                  # pushes the old directory onto the stack
setopt PUSHD_MINUS                 # exchange the meanings of '+' and '-'
setopt CDABLE_VARS                 # expand the expression (allows 'cd -2/tmp')
autoload -U compinit && compinit   # load + start completion
zstyle ':completion:*:directory-stack' list-colors '=(#b) #([0-9]#)*( *)==95=38;5;12'

结果:

在此处输入图片说明


4
bash bash bash bash
Tim

7
好的,我不会删除此答案,也许对其他人有用。
jimmij 2014年

23
除非问题特别询问bash,否则这是一个有效的答案。不要删除它。
liori

如果OP将他的问题编辑为仅包括bash,该答案仍然有效吗?
Ooker 2014年

3
也许值得一提的是,除了之外setopt AUTO_PUSHD不需要任何上述设置即可获得无所不在的目录堆栈,并在zsh中完成。PUSHD_MINUS颠倒了cd +and 的含义cd -(只是一个趣味),CDABLE_VARS与目录堆栈无关,zstyle这里给出的调用只是在目录堆栈完成输出中添加了颜色。但是,必须使用初始化完成子系统autoload -U compinit && compinit
wjv

13

回答有关“更多历史”的问题。cd -Bash中的功能均不支持您可以“翻转”到的单个目录。正如@Ramesh在回答中所说。如果您想要更长的目录历史记录,可以使用pushdpopd保存目录或返回上一个目录。

您还可以使用该dirs命令查看堆栈中当前内容的列表。

从标题为“ 我如何使用推入和弹出命令”的答案中可以找到详细说明


我已经从您的回答中提供了参考。希望你不要介意。:)
Ramesh 2014年

@Ramesh-不,继续吧。
slm

8

您可以安装我的dirhistory实用程序并将其用于bash。

基本上,它是一个守护程序,它从所有外壳程序中收集目录更改,而Cdk程序则显示历史记录,并允许您选择要切换到的任何目录(因此,您不仅限于堆栈)。


7

您拥有所需的历史记录:

cd() {
[ "$((${DIRSTACKMAX##*[!0-9]*}0/10))" -gt 0 ] &&
        set -- "$@" "$DIRSTACK"               &&
        DIRSTACK='pwd -P >&3; command cd'     ||
        { command cd "$@"; return; }
_q()    while   case "$1" in (*\'*) :   ;;      (*)
                ! DIRSTACK="$DIRSTACK '$2$1'"   ;;esac
        do      set -- "${1#*\'}" "$2${1%%\'*}'\''"
        done
while   [ "$#" -gt 1 ]
do      case    ${1:---} in (-|[!-]*|-*[!0-9]*) : ;;
        (*)     eval "  set $((${1#-}+1))"' "${'"$#}\""
                eval '  set -- "$2"'" $2"'
                        set -- "${'"$1"'}" "$1"'
        ;;esac; _q "$1"; shift
done
eval "  DIRSTACK=; $DIRSTACK    &&"'
        _q "$OLDPWD"            &&
        DIRSTACK=$DIRSTACK\ $1
        set "$?" "${DIRSTACK:=$1}"'" $1
"       3>/dev/null
[ "$(($#-1))" -gt "$DIRSTACKMAX" ] &&
        DIRSTACK="${DIRSTACK% \'/*}"
unset -f _q; return "$1"
}

这是一个外壳函数,应该使任何POSIX兼容外壳都能提供zsh-style cd历史记录。它无需调用一个子外壳即可完成所有工作,而且我相信它的流程非常合理-在适度的测试下,它似乎可以正确处理所有情况。

该函数尝试在仍完全依赖可移植语法的情况下尽可能好地发挥其环境的作用-它仅作一个假设,即$DIRSTACK环境变量是其将要使用的属性。

它可以规范化存储的所有路径,$DIRSTACK并使用单引号对所有路径进行序列化-尽管它确保在将每个路径添加到变量的值之前都对其进行安全的引用和序列化,并且任何类型的特殊字符都不会出现问题。如果$DIRSTACKMAX设置了环境变量,它将使用它作为历史记录中保留的路径数的上限,否则上限为1。

如果您cd正常加载该函数,但也可以cd -[num]通过更改目录历史记录进行追溯。

函数的主要机制是cd自身- ${OLD,}PWD环境变量。POSIX指定cd针对每个路径移动更改这些设置-因此,这仅使用Shell的内置变量并保存值,只要您愿意即可。


@datUser-我知道有人打过数据。非常欢迎您
-mikeserv


3

其他人已经介绍了一些有趣的解决方案。不久前,我为相关问题创建了自己的解决方案,可以迅速对其进行修改以实现“直接历史记录”。我基本上想“标记”一些常用目录,并希望所有打开的外壳都可以看到它们,并使它们在重新启动之间保持不变。

#dir_labels
#functions to load and retrieve list of dir aliases

function goto_complete {
    unset dir_labels
    declare -A dir_labels
    {
    while read line; do
        ll_pre="${line%% *}"
        ll_dir="${line#* }"
        dir_labels["$ll_pre"]="$ll_dir"
    done
    } < ~/.dir_labels
    unset ll_pre
    unset ll_dir

    local cur possib
    cur="${COMP_WORDS[COMP_CWORD]}"
    possib="${!dir_labels[@]}"
    COMPREPLY=( $(compgen -W "${possib}" -- ${cur}) )
}

complete -F goto_complete goto

function goto {
    unset dir_labels
    declare -A dir_labels
    {
    while read line; do
        ll_pre="${line%% *}"
        ll_dir="${line#* }"
        dir_labels["$ll_pre"]="$ll_dir"
    done
    } < ~/.dir_labels
    unset ll_pre
    unset ll_dir

    if [ $# -gt 0 ]; then
    key="$1"
    else
    key=default
    fi
    target="${dir_labels[$key]}"
    if [ -d "$target" ]; then
    cd "$target"
    echo "goto $key: '$target'"
    else
    echo "directory '$target' does not exist"
    fi
}

function label {
    unset dir_labels
    declare -A dir_labels
    {
    while read line; do
        ll_pre="${line%% *}"
        ll_dir="${line#* }"
        dir_labels["$ll_pre"]="$ll_dir"
    done
    } < ~/.dir_labels
    unset ll_pre
    unset ll_dir

    if [ $# -gt 0 ]; then
    target="$1"
    else
    target="default"
    fi
    dir_labels["$target"]=$PWD
    for i in "${!dir_labels[@]}"; do
    echo "$i ${dir_labels[$i]}"
    done > ~/.dir_labels
}

基本上,我只是做label foo调用当前目录下foo,然后从任何外壳,goto foo对子级cd直接出现。空参数:label将为创建默认目标goto

我没有费心实现别名的自动删除,但是除此之外,我仍然以稍微修改的形式使用它。


2

您可以从http://fex.belwue.de/fstools/bash.html使用我的“ cd历史记录”功能

它会记住您曾经去过的每个目录,并使用“ cdh”会看到最近9个目录的列表。只要输入数字,您就回到了这个目录。

例:

framstag @ wupp:/:CDH
1:/ usr / local / bin
2:/ var
3:/
4:/ tmp / 135_pana / 1280
5:/ tmp / 135_pana
6:/ tmp / weihnachtsfeier
7:/ tmp
8:/ local / home / framstag
选择:4
framstag @ wupp:/ tmp / 135_pana / 1280:

cdh可与autocd一起使用,也称为“无cd的CD”:您无需键入cd或pushed。


2

我想向您推荐扩展的“ cd”功能:

https://github.com/dczhu/ltcd

在此处输入图片说明

它提供以下功能以使生活更轻松:

  • 全球目录列表,显示所有终端标签/窗口中最近访问的目录。
  • 本地目录列表,对于当前Shell会话是本地的。
  • 两种清单都支持通过使用j / k(向下/向上),数字和单词搜索进行快速导航。
  • 全局自由跳转(例如,“ cd dir”或“ cd ar”转到/ path / to / foo / bar / directory /)。

嗯,看起来很有希望。我会检查出来的。
ddnomad

1

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


1

请参见第312页的“ Shell编程,4e”中的cdh函数。它将历史记录保存在数组中。

这是更高级的版本:https : //drive.google.com/open?id=0B4f-lR6inxQWQ1pPZVpUQ3FSZ2M

它将历史记录存储在文件CDHISTFILE中,并允许更改为包含字符串的最新目录,例如,

cd -src

通过执行以下操作,它将自身安装在现有cd命令上 alias cd=_cd


1

只是想添加fzf标记作为可能的解决方案。

安装完成后,它会为您提供命令标记跳转以添加和搜索已添加书签的目录(是的,它并不完全是完整的历史记录,只是您自己添加了书签的目录)。

我在推送/弹出会话特定行为方面遇到的问题,即我希望在不同的bash会话上具有相同的堆栈,因此fzf-marks可能这样做。


0

我尝试了@mikeserv给出的答案,但对我而言效果不佳。我不知道如何解决它,所以我只写了自己的:

cd() {
    # Set the current directory to the 0th history item
    cd_history[0]=$PWD
    if [[ $1 == -h ]]; then
        for i in ${!cd_history[@]}; do
            echo $i: "${cd_history[$i]}"
        done
        return
    elif [[ $1 =~ ^-[0-9]+ ]]; then
        builtin cd "${cd_history[${1//-}]}" || # Remove the argument's dash
        return 
    else
        builtin cd "$@" || return # Bail if cd fails
    fi
    # cd_history = ["", $OLDPWD, cd_history[1:]]
    cd_history=("" "$OLDPWD" "${cd_history[@]:1:${#cd_history[@]}}")
}

这也可以作为GitHub Gist获得。要使用此功能,只需将函数粘贴到您的函数.bashrc或类似函数中,您就可以执行操作,例如cd -5返回到您所访问的最后5 目录。这cd -h将为您提供历史记录的概述。

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.