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

相關內容