Ich liebe bash
(4.1.2(1)-Release), bevorzuge aber die Implementierungsweise tcsh
bei pushd +N
aktivierter dextract
Option so sehr, dass ich mich bash
deshalb weigere, sie als meine Standard-Shell zu verwenden. Hat jemand einen dextract
-ähnlichen Verzeichnisstapel-Befehlssatz implementiert bash
oder habe ich vielleicht noch nicht herausgefunden, wie ich es dazu bringen kann, sich bei aktivierter Option bash
wie zu verhalten ?tcsh
dextract
Der Knackpunkt: Die Reihenfolge, die bash
der Verzeichnisstapel nach einem hinterlässt pushd +N
. Zum Beispiel:
$ 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
Warum rotiert bash
(und standardmäßig tcsh
) die Positionen aller anderen Verzeichnisse, wenn ich ein mache pushd +1
? Warum ist das nützlich? (Vielleicht würde ich das Verhalten zu schätzen wissen und mich daran gewöhnen, wenn es mir jemand erklären würde.) Vergleichen Sie tcsh
mit dextract
, das es einfach extrahiert und oben platziert:
% 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
Beachten Sie, dass die restliche Reihenfolge der Verzeichnisse unverändert bleibt. Ich halte das für wichtig, da es für mich einfacher ist, den Überblick zu behalten, wenn die Reihenfolge nicht geändert wird, und ich so nicht immer dirs
nach dem gewünschten Verzeichnis suchen muss.
Wenn ich es versuchen würde, wo würde ich anfangen? Ich sehe, dass es eine Variable gibt DIRSTACK
, aber sie ist nicht korrekt (sie ist leer, wenn der Stapel vier Einträge hat), obwohl eine Änderung den Stapel ändert (allerdings nicht korrekt).
Antwort1
Nach einiger Arbeit und Inspiration habe ich mein Problem gelöst:
# 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
}