Czy mamy więcej historii na cd?


Odpowiedzi:


31

Polecenie, którego szukasz, to pushdi popd.

Można zobaczyć praktyczny przykład roboczą pushdi popdod 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

1
Są też $OLDPWDprzypadki, 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.
mechalynx

4
@ivy_lynx OLDPWDistnieje 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").
Gilles „SO- przestań być zły”

2
Czy jest jakiś powód, którego używasz cd /tmp/dir1; pushd . zamiast tylko pushd /tmp/dir1?
GnP

@gnp, bez konkretnego powodu. Właśnie zostało wzięte z linku, o którym wspomniałem w odpowiedzi. pushd /tmp/dir1powinien działać dobrze.
Ramesh

1
Ok, właśnie wybrałem moją ciekawość. Chciałbym zasugerować, abyś poprawił swoją odpowiedź, podając rzeczywisty przykład, używając pushdi popddo przeglądania drzewa katalogów tam iz powrotem. Twoja odpowiedź jest już poprawna.
GnP

53

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 -4itd. 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:

wprowadź opis zdjęcia tutaj


4
bash bash bash bash
Tim

7
OK, nie usunę tej odpowiedzi, być może będą przydatne dla innych.
jimmij

23
O ile pytanie nie dotyczy konkretnie tego pytania bash, jest to prawidłowa odpowiedź. Nie usuwaj go.
liori

Co się stanie, jeśli OP zmodyfikuje swoje pytanie tak, aby zawierało tylko bash, czy ta odpowiedź będzie nadal aktualna?
Ooker

3
Warto wspomnieć, że poza tym setopt AUTO_PUSHDżadna z powyższych konfiguracji nie jest wymagana, aby uzyskać wszechobecny stos katalogów z ukończeniem w magazynie zsh. PUSHD_MINUSodwraca sens cd +i cd -(kwestia gustu), nie CDABLE_VARSma znaczenia dla stosów katalogów, a zstylepodane 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.
wjv 07.04.16

13

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ć pushdi popdzapisać katalog lub powrócić do poprzedniego.

Możesz także zobaczyć listę tego, co aktualnie znajduje się na stosie za pomocą dirspolecenia.

Szczegółowe wyjaśnienie można znaleźć w tej odpowiedzi zatytułowanej: Jak korzystać z poleceń pushd i popd? .


Zawarłem odniesienie z twojej odpowiedzi. Mam nadzieję, że nie masz nic przeciwko. :)
Ramesh

@Ramesh - nie ma mowy.
slm

8

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).


7

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 zshstylu 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 $DIRSTACKzmienna środowiskowa jest jej własnością do zrobienia, jak chce.

Kanonizuje wszystkie ścieżki, w których się przechowuje, $DIRSTACKi 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 $DIRSTACKMAXzmienna ś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 cdjak 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 cdsama w sobie - i ${OLD,}PWDzmienne środowiskowe. POSIX określa, że cdzmieniają je dla każdego ruchu ścieżki - dlatego używa tylko wbudowanych zmiennych powłoki i zapisuje wartości tak długo, jak chcesz.


@datUser - wiedziałem, że ktoś ma dane. jesteś bardzo mile widziany
mikeserv


3

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 foowywołać bieżący katalog foo, a następnie z dowolnej powłoki, co goto fooby cdtam było bezpośrednio. Pusty argument: labelutworzył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.


2

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.


2

Chciałbym polecić Ci moją rozszerzoną funkcję „cd”:

https://github.com/dczhu/ltcd

wprowadź opis zdjęcia tutaj

Zapewnia następujące funkcje ułatwiające życie:

  • Globalna lista reż., Która pokazuje ostatnio przeglądane rewersy ze wszystkich kart / okien terminala.
  • Lokalny katalog katalogu, który jest lokalny dla bieżącej sesji powłoki.
  • Obie listy obsługują szybką nawigację za pomocą j / k (góra / dół), liczb i wyszukiwania słów.
  • Global free jumping (np. „Cd dir” lub „cd ar”, aby przejść do / path / to / foo / bar / directory /).

Hm, wygląda obiecująco. Sprawdzę to.
ddnomad

1

dla bash , w zasadzie: zamiast używać cd użyj pushddo 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 dirsi 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 cdi ~jak:

cd ~1

Ale teraz te liczby są teraz przestawiane i pozycja „0” ulegnie zmianie, więc wystarczy pushddwa 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)



1

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.


0

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ę .bashrclub podobny, a będziesz w stanie robić rzeczy, jak cd -5wrócić do 5 th ostatni katalog Byłaś w. cd -hDaje przegląd swojej historii.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.