在 bash 中获取类似 tcsh dextract 的 Pushd 功能

在 bash 中获取类似 tcsh dextract 的 Pushd 功能

我喜欢(4.1.2(1)-release),但我非常喜欢启用该选项的实现bash方式,以至于我拒绝将其用作我的默认 shell。有没有人实现了类似目录堆栈的命令集,或者也许我还没有弄清楚如何诱使行为像启用一样?tcshpushd +Ndextractbashdextractbashbashtcshdextract

症结所在:bashpushd +N.例如:

$ cd /tmp
$ pushd a
/tmp/a /tmp
$ pushd ../b
/tmp/b /tmp/a /tmp
$ pushd ../c
/tmp/c /tmp/b /tmp/a /tmp
$ pushd +1
/tmp/b /tmp/a /tmp /tmp/c

当我执行 a 时,为什么bash(默认情况下tcsh)会旋转所有其他目录的位置pushd +1?为什么这有用? (也许如果有人解释,我可能会欣赏这种行为并习惯它。)与tcshwith相比dextract,它只是提取它并将其放在顶部:

% set dextract
% cd /tmp
% pushd a
/tmp/a /tmp 
% pushd ../b
/tmp/b /tmp/a /tmp 
% pushd ../c
/tmp/c /tmp/b /tmp/a /tmp 
% pushd +1
/tmp/b /tmp/c /tmp/a /tmp 

请注意,目录的其余顺序保持不变。我认为这很重要,因为当订单不轮换时,我更容易在脑海中进行跟踪,因此我不必总是执行dirs并搜索我想要的目录。

如果我要尝试一下,我会从哪里开始呢?我看到有一个变量DIRSTACK,但它不正确(当堆栈有四个条目时它是空的),尽管更改它确实会改变堆栈(尽管不正确)。

答案1

经过一番工作和灵感,我解决了我的问题:

# dextract-like pushd -- push $1'st directory to top of stack and shift rest down
function pushd {
    local t
    if [[ $1 =~ ^[-+]?[0-9]+$ ]]; then
        pos=$1
        [[ ${pos} -lt 0 ]] && ((pos=${#DIRSTACK[@]}+${pos}))
        if [[ ${pos} -gt 0 && ${pos} -lt ${#DIRSTACK[@]} ]]; then
            t="${DIRSTACK[$pos]}"
            # This is crufty. You can't put ~ in DIRSTACK, except the
            # shell will put it into position zero when it refers to your
            # own directory (not anyone else's!). So replace any occurrences.
            DIRSTACK=("" "${DIRSTACK[0]/#~/${HOME}}" "${DIRSTACK[@]:1:${pos}-1}" "${DIRSTACK[@]:${pos}+1}")
            cd "$t"
            builtin dirs -v
        else
            echo "$0: pushd: $1: directory stack index out of range" 1>&2
        fi
    else
        builtin pushd "$@" >/dev/null || return
        cd .
        builtin dirs -v
    fi
}

相关内容