Antworten:
Der gesuchte Befehl ist pushd
und popd
.
Sie könnten ein praktisches Arbeitsbeispiel sehen pushd
und popd
von hier .
mkdir /tmp/dir1
mkdir /tmp/dir2
mkdir /tmp/dir3
mkdir /tmp/dir4
cd /tmp/dir1
pushd .
cd /tmp/dir2
pushd .
cd /tmp/dir3
pushd .
cd /tmp/dir4
pushd .
dirs
/tmp/dir4 /tmp/dir4 /tmp/dir3 /tmp/dir2 /tmp/dir1
$OLDPWD
Fall, dass Sie mit demselben Befehl zwischen zwei Verzeichnissen hin- und herschalten möchten, aber ich bin mir nicht sicher, wie Shell-spezifisch und Distributions- / Kernel-spezifisch dies ist.
OLDPWD
ist in allen POSIX-Shells vorhanden, aber für diese Frage, die danach fragt, wie man darüber hinausgeht, ist es nutzlos (die Frage erwähnt bereits, cd -
welche Abkürzung für steht cd "$OLDPWD"
).
cd /tmp/dir1; pushd .
anstelle von nur verwenden pushd /tmp/dir1
?
pushd /tmp/dir1
sollte gut funktionieren.
pushd
und popd
einen Verzeichnisbaum hin und her zu durchqueren. Ihre Antwort ist bereits richtig.
Sie haben nicht angegeben, welche Shell Sie verwenden. Lassen Sie dies also eine Ausrede sein, um für zsh zu werben.
Ja, tun wir mehr Geschichte für cd
, nämlich cd -2
, cd -4
usw. Sehr praktisch ist cd -
TAB, vor allem mit Komplettierungssystem und Farben aktiviert:
Das habe ich in .zshrc:
setopt AUTO_PUSHD # pushes the old directory onto the stack
setopt PUSHD_MINUS # exchange the meanings of '+' and '-'
setopt CDABLE_VARS # expand the expression (allows 'cd -2/tmp')
autoload -U compinit && compinit # load + start completion
zstyle ':completion:*:directory-stack' list-colors '=(#b) #([0-9]#)*( *)==95=38;5;12'
Und das Ergebnis:
bash
, ist dies eine gültige Antwort. Entfernen Sie es nicht.
setopt AUTO_PUSHD
keine der obigen Einstellungen erforderlich ist , um einen allgegenwärtigen Verzeichnisstack mit Fertigstellung in stock zsh zu erhalten. PUSHD_MINUS
Kehrt den Sinn von cd +
und um cd -
(Geschmackssache), CDABLE_VARS
ist für Verzeichnisstapel irrelevant, und der zstyle
hier angegebene Aufruf fügt der Ausgabe eines Verzeichnisstapelabschlusses einfach Farbe hinzu. Man muss jedoch das Vervollständigungssubsystem mit initialisieren autoload -U compinit && compinit
.
Um Ihre Frage zu "more history" zu beantworten. Nein, die cd -
Funktion in Bash unterstützt nur ein einziges Verzeichnis, in das Sie zurückkehren können. Wie @Ramesh in seiner Antwort feststellt. Wenn Sie einen längeren Verlauf von Verzeichnissen wünschen, können Sie mit pushd
und popd
ein Verzeichnis speichern oder zu einem vorherigen zurückkehren.
Mit dem dirs
Befehl können Sie auch die Liste der aktuell im Stapel befindlichen Elemente anzeigen.
Eine ausführliche Erklärung finden Sie in dieser Antwort mit dem Titel: Wie verwende ich die Befehle pushd und popd? .
Sie können mein Dienstprogramm dirhistory für bash installieren und verwenden .
Grundsätzlich ist es ein Daemon, der Verzeichnisänderungen von all Ihren Shells sammelt, und ein Cdk-Programm, das den Verlauf anzeigt und es Ihnen ermöglicht, jedes Verzeichnis auszuwählen, zu dem Sie wechseln möchten (Sie sind also nicht auf einen Stapel beschränkt).
Du hast so viel Geschichte wie du willst:
cd() {
[ "$((${DIRSTACKMAX##*[!0-9]*}0/10))" -gt 0 ] &&
set -- "$@" "$DIRSTACK" &&
DIRSTACK='pwd -P >&3; command cd' ||
{ command cd "$@"; return; }
_q() while case "$1" in (*\'*) : ;; (*)
! DIRSTACK="$DIRSTACK '$2$1'" ;;esac
do set -- "${1#*\'}" "$2${1%%\'*}'\''"
done
while [ "$#" -gt 1 ]
do case ${1:---} in (-|[!-]*|-*[!0-9]*) : ;;
(*) eval " set $((${1#-}+1))"' "${'"$#}\""
eval ' set -- "$2"'" $2"'
set -- "${'"$1"'}" "$1"'
;;esac; _q "$1"; shift
done
eval " DIRSTACK=; $DIRSTACK &&"'
_q "$OLDPWD" &&
DIRSTACK=$DIRSTACK\ $1
set "$?" "${DIRSTACK:=$1}"'" $1
" 3>/dev/null
[ "$(($#-1))" -gt "$DIRSTACKMAX" ] &&
DIRSTACK="${DIRSTACK% \'/*}"
unset -f _q; return "$1"
}
Dies ist eine Shell-Funktion, die es jeder POSIX-kompatiblen Shell ermöglichen sollte, eine Historie im zsh
Stile anzubieten cd
. Es erledigt all seine Arbeit, ohne eine einzige Subshell aufzurufen, und ich glaube, dass sein Fluss ziemlich gut ist - es scheint, alle Fälle unter moderaten Tests richtig zu behandeln.
Die Funktion versucht, so gut wie möglich mit ihrer Umgebung umzugehen, wobei sie sich auf eine vollständig portable Syntax stützt. Dabei wird nur eine Annahme getroffen, und zwar, dass die $DIRSTACK
Umgebungsvariable ihre Eigenschaft ist, mit der sie so zu tun hat, wie sie will.
Es kanonisiert alle Pfade, in denen es speichert, $DIRSTACK
und serialisiert sie in einfachen Anführungszeichen. Es stellt jedoch sicher, dass jeder Pfad sicher in Anführungszeichen gesetzt und serialisiert wird, bevor er zum Wert der Variablen hinzugefügt wird, und sollte keine Probleme mit Sonderzeichen jeglicher Art haben . Wenn die $DIRSTACKMAX
Umgebungsvariable festgelegt ist, wird sie als Obergrenze für die Anzahl der Pfade verwendet, die im Verlauf beibehalten werden. Andernfalls beträgt die Obergrenze eins.
Wenn Sie die Funktion cd
wie cd -[num]
gewohnt laden, können Sie sie aber auch zum Zurückverfolgen Ihres Änderungsverzeichnisverlaufs ausführen.
Der primäre Mechanismus der Funktion ist sie cd
selbst - und die ${OLD,}PWD
Umgebungsvariablen. POSIX gibt an, dass cd
diese bei jeder Pfadverschiebung geändert werden. Dabei werden nur die in der Shell integrierten Variablen verwendet und die Werte so lange gespeichert, wie Sie möchten.
Das Skript acd_func.sh macht genau das, was Sie beschreiben. Im Wesentlichen wird die cd
Funktion überlastet und Sie können eingeben cd --
, um eine Liste der zuvor besuchten Verzeichnisse abzurufen, aus denen Sie nach Nummer auswählen können. Ich finde es sehr schwierig, Bash ohne dieses zu verwenden, und es ist das erste, was ich auf einem neuen System installiere.
Andere behandelten bereits einige interessante Lösungen. Vor einiger Zeit habe ich meine eigene Lösung für ein verwandtes Problem entwickelt, das schnell geändert werden kann, um "Straight History" zu erstellen. Grundsätzlich wollte ich ein paar häufig verwendete Verzeichnisse "beschriften" und wollte, dass alle offenen Shells sie sehen und zwischen den Neustarts beibehalten.
#dir_labels
#functions to load and retrieve list of dir aliases
function goto_complete {
unset dir_labels
declare -A dir_labels
{
while read line; do
ll_pre="${line%% *}"
ll_dir="${line#* }"
dir_labels["$ll_pre"]="$ll_dir"
done
} < ~/.dir_labels
unset ll_pre
unset ll_dir
local cur possib
cur="${COMP_WORDS[COMP_CWORD]}"
possib="${!dir_labels[@]}"
COMPREPLY=( $(compgen -W "${possib}" -- ${cur}) )
}
complete -F goto_complete goto
function goto {
unset dir_labels
declare -A dir_labels
{
while read line; do
ll_pre="${line%% *}"
ll_dir="${line#* }"
dir_labels["$ll_pre"]="$ll_dir"
done
} < ~/.dir_labels
unset ll_pre
unset ll_dir
if [ $# -gt 0 ]; then
key="$1"
else
key=default
fi
target="${dir_labels[$key]}"
if [ -d "$target" ]; then
cd "$target"
echo "goto $key: '$target'"
else
echo "directory '$target' does not exist"
fi
}
function label {
unset dir_labels
declare -A dir_labels
{
while read line; do
ll_pre="${line%% *}"
ll_dir="${line#* }"
dir_labels["$ll_pre"]="$ll_dir"
done
} < ~/.dir_labels
unset ll_pre
unset ll_dir
if [ $# -gt 0 ]; then
target="$1"
else
target="default"
fi
dir_labels["$target"]=$PWD
for i in "${!dir_labels[@]}"; do
echo "$i ${dir_labels[$i]}"
done > ~/.dir_labels
}
Grundsätzlich würde ich einfach label foo
das aktuelle Verzeichnis aufrufen foo
, und dann von welcher Shell auch immer, goto foo
was cd
direkt dort wäre. Leeres Argument: label
Erstellt ein Standardziel für goto
.
Ich habe mich nicht darum gekümmert, das automatische Entfernen von Aliasen zu implementieren, aber ansonsten verwende ich dies immer noch in leicht modifizierter Form.
Sie können meine "cd history" -Funktion unter http://fex.belwue.de/fstools/bash.html verwenden
Es merkt sich jedes Verzeichnis, in dem Sie waren und mit "cdh" sehen Sie eine Liste der letzten 9 Verzeichnisse. Geben Sie einfach die Nummer ein und Sie sind wieder in diesem Verzeichnis.
Beispiel:
framstag @ wupp: /: cdh 1: / usr / local / bin 2: / var 3: / 4: / tmp / 135_pana / 1280 5: / tmp / 135_pana 6: / tmp / weihnachtsfeier 7: / tmp 8: / local / home / framstag auswählen: 4 framstag @ wupp: / tmp / 135_pana / 1280:
cdh funktioniert mit autocd aka "cd without cd": Sie müssen weder cd noch pushd eingeben.
Ich möchte Ihnen meine erweiterte CD-Funktion empfehlen:
Es bietet die folgenden Funktionen, um das Leben zu erleichtern:
für bash im grunde: anstatt cd zu verwenden, um verzeichnisse pushd
zu wechseln, werden sie gespeichert (dh gestapelt)
pushd /home; pushd /var; pushd log
Um den Stack zu sehen, benutzen Sie dirs
und zur einfacheren Navigation (um die Nummern der "Stack-Einträge" zu erhalten, benutzen Sie:
dirs -v
Ausgabe:
me@myhost:/home$ dirs -v
0 /home
1 /var
2 /tmp
Verwenden Sie nun diese Zahlen mit cd
und ~
wie:
cd ~1
Aber jetzt sind diese Nummern neu angeordnet und Position "0" ändert sich, so dass nur pushd
das Verzeichnis zweimal an die oberste Position (oder verwenden Sie einen Dummy auf Position 0) wie folgt :
me@myhost:/home$ dirs -v
0 /home
1 /home
2 /var
3 /tmp
jetzt wird 1..3 dort stehen bleiben. Ich habe das irgendwo gelesen, weiß es aber nicht mehr
(um das aktuelle Verzeichnis vom Stack zu entfernen / aus dem Verlauf zu löschen popd
)
Siehe die cdh-Funktion in "Shell-Programmierung, 4e" auf Seite 349. Sie speichert den Verlauf in einem Array.
Hier ist eine erweiterte Version: https://drive.google.com/open?id=0B4f-lR6inxQWQ1pPZVpUQ3FSZ2M
Es speichert den Verlauf in der Datei CDHISTFILE und ermöglicht das Wechseln in das neueste Verzeichnis, das eine Zeichenfolge enthält, z.
cd -src
Es installiert sich über den vorhandenen Befehl cd, indem es ein alias cd=_cd
Ich wollte nur fzf-Marken als mögliche Lösung hinzufügen .
Einmal installiert, gibt es Ihnen die Befehle Markieren und Springen , um mit Lesezeichen versehene Verzeichnisse hinzuzufügen und zu suchen (ja, das ist nicht genau der vollständige Verlauf, nur die, die Sie selbst mit Lesezeichen versehen haben).
Das Problem, das ich mit pushd / popd it habe, ist das sitzungsspezifische Verhalten, dh ich möchte den gleichen Stack in einer anderen Bash-Sitzung haben oder so, was für FZF-Marken möglich ist.
Ich habe die Antwort von @mikeserv ausprobiert, aber es hat bei mir nicht ganz funktioniert. Ich konnte nicht herausfinden, wie ich das Problem beheben kann, und schrieb einfach meine eigenen:
cd() {
# Set the current directory to the 0th history item
cd_history[0]=$PWD
if [[ $1 == -h ]]; then
for i in ${!cd_history[@]}; do
echo $i: "${cd_history[$i]}"
done
return
elif [[ $1 =~ ^-[0-9]+ ]]; then
builtin cd "${cd_history[${1//-}]}" || # Remove the argument's dash
return
else
builtin cd "$@" || return # Bail if cd fails
fi
# cd_history = ["", $OLDPWD, cd_history[1:]]
cd_history=("" "$OLDPWD" "${cd_history[@]:1:${#cd_history[@]}}")
}
Dies ist auch als GitHub Gist verfügbar . Um dies zu nutzen, fügen Sie einfach die Funktion in Ihre .bashrc
oder ähnlich, und Sie werden in der Lage sein , die Dinge zu tun , wie cd -5
zum 5 zurück th letzten Verzeichnis , das Sie in sind. cd -h
Gibt Ihnen einen Überblick über Ihre Geschichte.