Risposte:
Il comando che stai cercando è pushd
e popd
.
È possibile visualizzare un esempio pratico di lavoro di pushd
e popd
da 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
$OLDPWD
nel 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.
OLDPWD
esiste 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"
).
cd /tmp/dir1; pushd .
invece di solo pushd /tmp/dir1
?
pushd /tmp/dir1
dovrebbe funzionare bene.
pushd
e popd
attraversare avanti e indietro un albero di directory. La tua risposta è già quella corretta.
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 -4
ecc. 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:
bash
, questa è una risposta valida. Non rimuoverlo.
setopt AUTO_PUSHD
, nessuna delle impostazioni di cui sopra è necessaria per ottenere uno stack di directory onnipresente con completamento in stock zsh. PUSHD_MINUS
inverte il senso di cd +
e cd -
(una questione di gusti), CDABLE_VARS
è irrilevante per gli stack di directory e l' zstyle
invocazione 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
.
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 pushd
e popd
salvare una directory o tornare a una precedente.
Puoi anche vedere l'elenco di ciò che è attualmente nello stack con il dirs
comando.
Una spiegazione dettagliata può essere trovata da questa risposta intitolata: Come posso usare i comandi pushd e popd? .
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).
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 zsh
stile 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 $DIRSTACK
variabile d'ambiente è la sua proprietà a che fare come vuole.
Canonicalizza tutti i percorsi in cui memorizza $DIRSTACK
e 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 $DIRSTACKMAX
variabile 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 cd
come 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 cd
stesso - e le ${OLD,}PWD
variabili di ambiente. POSIX specifica che cd
cambiano 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.
Lo script acd_func.sh fa esattamente quello che descrivi. Sostanzialmente sovraccarica la cd
funzione e consente di digitare cd --
per ottenere un elenco di directory precedentemente visitate, da cui è possibile selezionare in base al numero. Trovo molto difficile usare bash senza questo, ed è la prima cosa che installo su un nuovo sistema.
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 foo
a chiamare la directory corrente foo
, e quindi da qualsiasi shell, goto foo
whould cd
direttamente lì. Argomento vuoto: label
creerebbe 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.
È 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.
Vorrei raccomandarti la mia funzione estesa "cd":
Fornisce le seguenti funzionalità per semplificare la vita:
per bash , in sostanza: invece di usare cd usare pushd
per cambiare directory, quindi vengono salvati (nel senso in pila)
pushd /home; pushd /var; pushd log
Per vedere lo stack utilizzare dirs
e 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 cd
e ~
simili:
cd ~1
Ma ora questi numeri sono ora riorganizzati e la posizione "0" cambierà, quindi solo pushd
la 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
)
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
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.
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 .bashrc
o in una simile e sarai in grado di fare cose come cd -5
tornare all'ultima quinta directory in cui ti sei trovato. cd -h
Ti darà una panoramica della tua cronologia.