Eu adoro bash
(4.1.2(1)-release) mas prefiro fortemente a forma como tcsh
é implementado pushd +N
com a dextract
opção habilitada, tanto que me recuso a usar bash
como meu shell padrão por causa disso. Alguém implementou um dextract
conjunto de comandos de pilha de diretórios semelhante a bash
ou talvez eu não tenha descoberto como persuadir bash
a se comportar como tcsh
ativado dextract
?
O ponto crítico: a ordem que bash
deixa a pilha de diretórios depois de um arquivo pushd +N
. Por exemplo:
$ 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
Por que bash
(e o padrão tcsh
) gira as posições de todos os outros diretórios quando eu faço um pushd +1
? Por que isso é útil? (Talvez se alguém explicasse, eu apreciaria o comportamento e me acostumaria com ele.) Compare com tcsh
with dextract
, que apenas extrai e coloca no topo:
% 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
Observe que a ordem restante dos diretórios permanece intacta. Considero isso importante porque é mais fácil manter o controle em minha mente quando o pedido não é alternado e, portanto, não preciso ficar sempre dirs
pesquisando o diretório que desejo.
Se eu tentasse, por onde começaria? Vejo que há uma variável DIRSTACK
, mas ela não está correta (está vazia quando a pilha tem quatro entradas), embora alterá-la altere a pilha (embora não corretamente).
Responder1
Depois de algum trabalho e inspiração, resolvi meu problema:
# 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
}