Me encanta bash
(versión 4.1.2(1)), pero prefiero la forma en que tcsh
se implementa pushd +N
con la dextract
opción habilitada, hasta el punto de que me niego a usarla bash
como mi shell predeterminado por eso. ¿Alguien ha implementado un dextract
conjunto de comandos de pila de directorio similar a -o bash
tal vez no he descubierto cómo lograr bash
que se comporte como tcsh
si dextract
estuviera habilitado?
El punto conflictivo: el orden en que bash
sale la pila de directorios después de un archivo pushd +N
. Por ejemplo:
$ 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 qué bash
(y por defecto tcsh
) rota las posiciones de todos los demás directorios cuando hago un pushd +1
? ¿Por qué es esto útil? (Quizás si alguien me lo explicara, podría apreciar el comportamiento y acostumbrarme a él). Compárelo con tcsh
with dextract
, que simplemente lo extrae y lo coloca encima:
% 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
Tenga en cuenta que el orden restante de los directorios no se modifica. Considero que esto es importante porque es más fácil realizar un seguimiento en mi mente cuando el orden no se rota, y así no tengo que estar siempre dirs
buscando el directorio que quiero.
Si tuviera que intentarlo, ¿por dónde empezaría? Veo que hay una variable DIRSTACK
, pero no es correcta (está vacía cuando la pila tiene cuatro entradas), aunque cambiarla altera la pila (aunque no correctamente).
Respuesta1
Después de un poco de trabajo e inspiración, resolví mi 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
}