Abbiamo più storia per il cd?


Risposte:


31

Il comando che stai cercando è pushde popd.

È possibile visualizzare un esempio pratico di lavoro di pushde popdda qui .

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
C'è anche $OLDPWDnel caso in cui si desideri alternare due directory usando lo stesso comando, ma non sono sicuro di quanto sia specifico per shell e per distribuzione / kernel specifico.
mechalynx,

4
@ivy_lynx OLDPWDesiste in tutte le shell POSIX, ma è inutile per questa domanda che chiede come andare oltre (la domanda menziona già cd -che è una scorciatoia cd "$OLDPWD").
Gilles 'SO- smetti di essere malvagio' il

2
C'è un motivo che usi cd /tmp/dir1; pushd . invece di solo pushd /tmp/dir1?
GnP,

@gnp, nessun motivo specifico. È stato appena preso dal link a cui ho fatto riferimento nella risposta. pushd /tmp/dir1dovrebbe funzionare bene.
Ramesh,

1
Ok, ho appena scelto la mia curiosità. Vorrei suggerirti di migliorare la tua risposta con un esempio reale usando pushde popdattraversare avanti e indietro un albero di directory. La tua risposta è già quella corretta.
GnP,

54

Non hai specificato quale shell stai usando, quindi lascia che sia una scusa per pubblicizzare zsh.

Sì, abbiamo più storia per cd, vale a dire cd -2, cd -4ecc. Molto conveniente è cd -TAB, specialmente con il sistema di completamento e i colori abilitati:

Questo è quello che ho 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'

E il risultato:

inserisci qui la descrizione dell'immagine


4
bash bash bash bash
Tim

7
OK, non eliminerò questa risposta, forse sarà utile per gli altri.
jimmij,

23
A meno che la domanda non sia specificamente rivolta bash, questa è una risposta valida. Non rimuoverlo.
liori,

Che cosa succede se il PO modifica la sua domanda per includere solo bash, questa risposta sarà ancora valida?
Ooker,

3
Potrebbe essere opportuno menzionare che, a parte setopt AUTO_PUSHD, nessuna delle impostazioni di cui sopra è necessaria per ottenere uno stack di directory onnipresente con completamento in stock zsh. PUSHD_MINUSinverte il senso di cd +e cd -(una questione di gusti), CDABLE_VARSè irrilevante per gli stack di directory e l' zstyleinvocazione fornita qui aggiunge semplicemente colorazione all'output di un completamento dello stack di directory. Bisogna comunque inizializzare il sottosistema di completamento con autoload -U compinit && compinit.
wjv,

13

Per rispondere alla tua domanda su "più storia". No, la cd -funzionalità di Bash supporta solo una singola directory in cui è possibile "tornare indietro". Come afferma @Ramesh nella sua risposta. Se si desidera una cronologia più lunga delle directory, è possibile utilizzare pushde popdsalvare una directory o tornare a una precedente.

Puoi anche vedere l'elenco di ciò che è attualmente nello stack con il dirscomando.

Una spiegazione dettagliata può essere trovata da questa risposta intitolata: Come posso usare i comandi pushd e popd? .


Ho incluso un riferimento dalla tua risposta. Spero non ti dispiaccia. :)
Ramesh,

@Ramesh - no vai avanti.
slm

8

Puoi installare e usare la mia utility dirhistory per bash.

Fondamentalmente, è un demone che raccoglie le modifiche alla directory da tutte le tue shell e un programma Cdk che mostra la cronologia e ti consente di scegliere qualsiasi directory su cui passare (quindi non sei limitato a uno stack).


7

Hai tutta la storia che vuoi:

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"
}

Questa è una funzione di shell che dovrebbe consentire a qualsiasi shell compatibile con POSIX di offrire la cronologia in zshstile cd. Fa tutto il suo lavoro senza invocare una singola subshell e credo che il suo flusso sia piuttosto solido - sembra che gestisca correttamente tutti i casi con test moderati.

La funzione tenta di giocare il più bene possibile con il suo ambiente mentre fa ancora affidamento su una sintassi completamente portatile: fa solo un presupposto e cioè che la $DIRSTACKvariabile d'ambiente è la sua proprietà a che fare come vuole.

Canonicalizza tutti i percorsi in cui memorizza $DIRSTACKe li serializza su virgolette singole, sebbene assicuri che ciascuno sia quotato e serializzato in modo sicuro prima di aggiungerlo al valore della variabile e non dovrebbe avere alcun problema con caratteri speciali di qualsiasi tipo . Se la $DIRSTACKMAXvariabile di ambiente è impostata, la utilizzerà come limite superiore per il numero di percorsi che mantiene nella cronologia, altrimenti il ​​limite è uno.

Se carichi la funzione cdcome al solito, ma sarai anche in grado di fare ciò cd -[num]per tornare indietro nella cronologia delle modifiche.

Il meccanismo principale della funzione è esso cdstesso - e le ${OLD,}PWDvariabili di ambiente. POSIX specifica che cdcambiano queste per ogni spostamento del percorso - e quindi questo utilizza solo le variabili incorporate della shell e salva i valori per tutto il tempo che desideri.


@datUser - sapevo che qualcuno aveva un dat. sei il benvenuto
mikeserv


3

Altri hanno già trattato alcune soluzioni interessanti. Qualche tempo fa ho creato la mia soluzione a un problema correlato che potrebbe essere rapidamente modificato per fare una "storia semplice". In pratica volevo "etichettare" alcune directory comunemente usate e volevo che tutte le shell aperte le vedessero e che persistessero tra i riavvii.

#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
}

In fondo avevo appena faccio label fooa chiamare la directory corrente foo, e quindi da qualsiasi shell, goto foowhould cddirettamente lì. Argomento vuoto: labelcreerebbe una destinazione predefinita per goto.

Non mi sono preoccupato di implementare la rimozione automatica degli alias, ma per il resto lo sto ancora usando in una forma leggermente modificata.


2

È possibile utilizzare la mia funzione "cronologia cd" da http://fex.belwue.de/fstools/bash.html

Ricorda ogni directory in cui sei stato e con "cdh" vedrai un elenco delle ultime 9 directory. Basta inserire il numero e sei tornato in questa directory.

Esempio:

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
seleziona: 4
framstag @ Wupp: / tmp / 135_pana / 1280:

cdh funziona con autocd aka "cd senza cd": non è necessario digitare cd o pushd.


2

Vorrei raccomandarti la mia funzione estesa "cd":

https://github.com/dczhu/ltcd

inserisci qui la descrizione dell'immagine

Fornisce le seguenti funzionalità per semplificare la vita:

  • Elenco globale delle directory, che mostra le directory visitate di recente da tutte le schede / finestre del terminale.
  • Elenco di directory locale, che è locale alla sessione di shell corrente.
  • Entrambi gli elenchi supportano la navigazione rapida utilizzando j / k (vai su / giù), i numeri e la ricerca di parole.
  • Salto libero globale (ad es. "Cd dir" o "cd ar" per accedere a / path / to / foo / bar / directory /).

Hm, sembra promettente. Lo controllerò.
ddnomad,

1

per bash , in sostanza: invece di usare cd usare pushdper cambiare directory, quindi vengono salvati (nel senso in pila)

pushd /home; pushd /var; pushd log

Per vedere lo stack utilizzare dirse per una navigazione più semplice (per ottenere i numeri delle "voci dello stack" utilizzare:

dirs -v

Produzione:

me@myhost:/home$ dirs -v
 0  /home
 1  /var
 2  /tmp

Ora utilizza questi numeri con cde ~simili:

cd ~1

Ma ora questi numeri sono ora riorganizzati e la posizione "0" cambierà, quindi solo pushdla directory nella posizione più alta due volte (o usa un manichino nella posizione 0) come:

me@myhost:/home$ dirs -v
 0  /home
 1  /home
 2  /var
 3  /tmp

ora 1..3 manterrà lì la posizione, l' ho letto da qualche parte ma non lo so più, quindi scusami per non aver dato credito

(per rilasciare la directory corrente dallo stack / eliminarla dall'uso della cronologia popd)


1

Vedere la funzione cdh in "Programmazione Shell, 4e" a pagina 312. Mantiene la cronologia in un array.

Ecco una versione più avanzata: https://drive.google.com/open?id=0B4f-lR6inxQWQ1pPZVpUQ3FSZ2M

Memorizza la cronologia nel file CDHISTFILE e consente di passare alla directory più recente che contiene una stringa, ad es.

cd -src

Si installa sul comando cd esistente eseguendo un comando alias cd=_cd


1

Volevo solo aggiungere i marchi fzf come possibile soluzione.

Una volta installato, ti dà il segno e il salto per aggiungere e cercare le directory con segnalibro (sì, non è esattamente la cronologia completa, solo quelle che hai aggiunto ai segnalibri).

Il problema che ho con pushd / popd è un comportamento specifico della sessione, cioè mi piacerebbe avere lo stesso stack su diverse sessioni bash o giù di lì che è possibile per i marchi fzf.


0

Ho provato la risposta che mi ha dato @mikeserv, ma per me non ha funzionato. Non sono riuscito a capire come risolverlo, quindi ho appena scritto il mio:

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[@]}}")
}

Questo è disponibile anche come GitHub Gist . Per usarlo, basta incollare la funzione nella tua .bashrco in una simile e sarai in grado di fare cose come cd -5tornare all'ultima quinta directory in cui ti sei trovato. cd -hTi darà una panoramica della tua cronologia.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.