Odpowiedzi:
Polecenie, którego szukasz, to pushd
i popd
.
Można zobaczyć praktyczny przykład roboczą pushd
i popd
od tutaj .
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
przypadki, gdy chcesz przerzucać się między dwoma katalogami za pomocą tego samego polecenia, ale nie jestem pewien, czy jest to specyficzne dla powłoki i specyficzne dla dystrybucji / jądra.
OLDPWD
istnieje we wszystkich powłokach POSIX, ale jest bezużyteczny w przypadku tego pytania, które pyta, jak wyjść poza to (pytanie już wspomina, cd -
który jest skrótem cd "$OLDPWD"
).
cd /tmp/dir1; pushd .
zamiast tylko pushd /tmp/dir1
?
pushd /tmp/dir1
powinien działać dobrze.
pushd
i popd
do przeglądania drzewa katalogów tam iz powrotem. Twoja odpowiedź jest już poprawna.
Nie określiłeś, której powłoki używasz, więc niech to będzie wymówka do reklamowania zsh.
Tak, mamy więcej historię cd
, mianowicie cd -2
, cd -4
itd. Bardzo wygodna jest cd -
TAB, zwłaszcza z systemem wykończenia i kolory włączone:
Oto, co mam w .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'
A wynik:
bash
, jest to prawidłowa odpowiedź. Nie usuwaj go.
setopt AUTO_PUSHD
żadna z powyższych konfiguracji nie jest wymagana, aby uzyskać wszechobecny stos katalogów z ukończeniem w magazynie zsh. PUSHD_MINUS
odwraca sens cd +
i cd -
(kwestia gustu), nie CDABLE_VARS
ma znaczenia dla stosów katalogów, a zstyle
podane tutaj wywołanie po prostu dodaje kolorowanie do wyniku ukończenia stosu katalogów. Należy jednak zainicjować podsystem ukończenia za pomocą autoload -U compinit && compinit
.
Aby odpowiedzieć na pytanie dotyczące „więcej historii”. Nie. cd -
Funkcja w Bash obsługuje tylko jeden katalog, do którego można „przerzucić” z powrotem. Jak stwierdza @Ramesh w swojej odpowiedzi. Jeśli chcesz mieć dłuższą historię katalogów, możesz użyć pushd
i popd
zapisać katalog lub powrócić do poprzedniego.
Możesz także zobaczyć listę tego, co aktualnie znajduje się na stosie za pomocą dirs
polecenia.
Szczegółowe wyjaśnienie można znaleźć w tej odpowiedzi zatytułowanej: Jak korzystać z poleceń pushd i popd? .
Możesz zainstalować i używać mojego narzędzia dirhistory do bash.
Zasadniczo jest to demon, który zbiera zmiany katalogów ze wszystkich twoich powłok, oraz program Cdk, który wyświetla historię i pozwala wybrać dowolny katalog do przełączenia (więc nie jesteś ograniczony do stosu).
Masz tyle historii, ile chcesz:
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"
}
Jest to funkcja powłoki, która powinna umożliwić dowolnej powłoce kompatybilnej z POSIX oferowanie historii w zsh
stylu cd
. Wykonuje całą swoją pracę bez wywoływania pojedynczej podpowłoki i uważam, że jego przepływ jest całkiem niezły - wydaje się, że poprawnie obsługuje wszystkie przypadki przy umiarkowanych testach.
Funkcja stara się grać z otoczeniem tak dobrze, jak to możliwe, wciąż polegając na w pełni przenośnej składni - przyjmuje tylko jedno założenie, a mianowicie, że $DIRSTACK
zmienna środowiskowa jest jej własnością do zrobienia, jak chce.
Kanonizuje wszystkie ścieżki, w których się przechowuje, $DIRSTACK
i serializuje je wszystkie w pojedynczych cudzysłowach - chociaż zapewnia, że każda z nich jest bezpiecznie cytowana i serializowana przed dodaniem jej do wartości zmiennej i nie powinna mieć problemów z żadnymi znakami specjalnymi jakiegokolwiek rodzaju . Jeśli $DIRSTACKMAX
zmienna środowiskowa jest ustawiona, użyje jej jako górnego limitu liczby ścieżek, które zachowuje w historii, w przeciwnym razie limit jest jeden.
Jeśli załadujesz funkcję tak cd
jak zwykle, ale będziesz mógł również zrobić to, cd -[num]
aby prześledzić historię zmian w katalogu zmian.
Podstawowym mechanizmem tej funkcji jest cd
sama w sobie - i ${OLD,}PWD
zmienne środowiskowe. POSIX określa, że cd
zmieniają je dla każdego ruchu ścieżki - dlatego używa tylko wbudowanych zmiennych powłoki i zapisuje wartości tak długo, jak chcesz.
Acd_func.sh skrypt robi dokładnie to, co opisujesz. Zasadniczo przeciąża cd
funkcję i umożliwia pisanie, aby cd --
uzyskać listę poprzednio odwiedzanych katalogów, z których można wybrać numer. Bez tego bardzo trudno mi używać bash, a to pierwsza rzecz, którą instaluję na nowym systemie.
Inne dotyczyły już kilku interesujących rozwiązań. Jakiś czas temu stworzyłem własne rozwiązanie pokrewnego problemu, które można szybko zmodyfikować, aby tworzyć „prostą historię”. Zasadniczo chciałem „opatrzyć etykietą” kilka często używanych katalogów i chciałem, aby wszystkie otwarte powłoki je widziały i aby pozostawały między restartami.
#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
}
Zasadniczo zrobiłbym po prostu label foo
wywołać bieżący katalog foo
, a następnie z dowolnej powłoki, co goto foo
by cd
tam było bezpośrednio. Pusty argument: label
utworzyłby domyślny cel dla goto
.
Nie zawracałem sobie głowy wdrażaniem automatycznego usuwania aliasów, ale poza tym nadal używam tego w nieco zmodyfikowanej formie.
Możesz użyć mojej funkcji „historii CD” ze strony http://fex.belwue.de/fstools/bash.html
Zapamiętuje każdy katalog, w którym byłeś, a wraz z „cdh” zobaczysz listę 9 ostatnich katalogów. Po prostu wpisz numer i wrócisz do tego katalogu.
Przykład:
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 wybierz: 4 framstag @ wupp: / tmp / 135_pana / 1280:
cdh działa z autocd aka „cd bez cd”: nie musisz wpisywać cd ani pushd.
Chciałbym polecić Ci moją rozszerzoną funkcję „cd”:
Zapewnia następujące funkcje ułatwiające życie:
dla bash , w zasadzie: zamiast używać cd użyj pushd
do zmiany katalogów, więc są one zapisywane (czyli ułożone w stos)
pushd /home; pushd /var; pushd log
Aby zobaczyć użycie stosu dirs
i ułatwić nawigację (aby uzyskać numery „wpisów stosu”, użyj:
dirs -v
Wynik:
me@myhost:/home$ dirs -v
0 /home
1 /var
2 /tmp
Teraz wykorzystać te numery z cd
i ~
jak:
cd ~1
Ale teraz te liczby są teraz przestawiane i pozycja „0” ulegnie zmianie, więc wystarczy pushd
dwa razy katalog do najwyższej pozycji (lub użyć manekina na pozycji 0), np .:
me@myhost:/home$ dirs -v
0 /home
1 /home
2 /var
3 /tmp
teraz 1..3 utrzyma tam pozycję Przeczytałem to gdzieś, ale już nie wiem, więc przepraszam, że nie wyraziłem uznania
(aby zwolnić bieżący katalog ze stosu / usunąć go z historii popd
)
Zobacz funkcję cdh w „Programowaniu powłoki, 4e” na stronie 312. Utrzymuje historię w tablicy.
Oto bardziej zaawansowana wersja: https://drive.google.com/open?id=0B4f-lR6inxQWQ1pPZVpUQ3FSZ2M
Przechowuje historię w pliku CDHISTFILE i umożliwia przejście do najnowszego katalogu zawierającego ciąg znaków, np.
cd -src
Instaluje się na istniejącym poleceniu cd, wykonując polecenie alias cd=_cd
Chciałem tylko dodać znaki fzf jako możliwe rozwiązanie.
Po zainstalowaniu daje ci znak komend i przeskakuje, aby dodać i wyszukać katalogi z zakładkami (tak, to nie jest dokładnie pełna historia, tylko te, które sam dodałeś do zakładek).
Problem, który mam z zachowaniem specyficznym dla sesji pushd / popd it, tzn. Chciałbym mieć ten sam stos w różnych sesjach bash lub tak, co jest możliwe dla znaków fzf.
Próbowałem odpowiedzi udzielonej przez @mikeserv, ale dla mnie to nie zadziałało. Nie mogłem wymyślić, jak to naprawić, więc po prostu napisałem własny:
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[@]}}")
}
Jest to również dostępne jako GitHub Gist . Aby to wykorzystać, wystarczy wkleić na swoją funkcję .bashrc
lub podobny, a będziesz w stanie robić rzeczy, jak cd -5
wrócić do 5 th ostatni katalog Byłaś w. cd -h
Daje przegląd swojej historii.