Respuestas:
El comando que está buscando es pushd
y popd
.
Puede ver un ejemplo práctico de trabajo desde pushd
y popd
desde aquí .
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
en caso de que desee alternar entre dos directorios con el mismo comando, pero no estoy seguro de cómo es esto específico de shell y de distribución / kernel.
OLDPWD
existe en todos los shells POSIX, pero es inútil para esta pregunta que pregunta cómo ir más allá (la pregunta ya menciona cd -
cuál es un atajo para cd "$OLDPWD"
).
cd /tmp/dir1; pushd .
lugar de solo pushd /tmp/dir1
?
pushd /tmp/dir1
debería funcionar bien.
pushd
y popd
para recorrer un árbol de directorios de un lado a otro. Tu respuesta ya es la correcta.
No especificó qué shell está utilizando, así que deje que esto sea una excusa para anunciar zsh.
Sí, tenemos más historial para cd
, a saber cd -2
, cd -4
etc. Es muy conveniente cd -
TAB, especialmente con el sistema de terminación y los colores habilitados:
Esto es lo que tengo en .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'
Y el resultado:
bash
, esta es una respuesta válida. No lo quites.
setopt AUTO_PUSHD
, no se requiere ninguna de las configuraciones anteriores para obtener una pila de directorios omnipresente con finalización en stock zsh. PUSHD_MINUS
invierte el sentido de cd +
y cd -
(una cuestión de gustos), CDABLE_VARS
es irrelevante para las pilas de directorios, y la zstyle
invocación dada aquí simplemente agrega color a la salida de la finalización de una pila de directorios. Sin embargo, se debe inicializar el subsistema de finalización con autoload -U compinit && compinit
.
Para responder a su pregunta sobre "más historia". No, la cd -
función en Bash solo admite un único directorio al que puede "voltear". Como @Ramesh afirma en su respuesta. Si desea un historial más largo de directorios, puede usar pushd
y popd
guardar un directorio o volver a uno anterior.
También puede ver la lista de lo que está actualmente en la pila con el dirs
comando.
Se puede encontrar una explicación detallada de esta respuesta titulada: ¿Cómo uso los comandos pushd y popd? .
Puede instalar y usar mi utilidad dirhistory para bash.
Básicamente, es un demonio que recopila cambios de directorio de todos sus shells, y un programa Cdk que muestra el historial y le permite elegir cualquier directorio para cambiar (por lo que no está limitado a una pila).
Tienes tanta historia como quieras:
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"
}
Esa es una función de shell que debería permitir que cualquier shell compatible con POSIX ofrezca un historial de zsh
estilo cd
. Hace todo su trabajo sin invocar una sola subshell, y creo que su flujo es bastante sólido: parece manejar todos los casos correctamente bajo pruebas moderadas.
La función intenta jugar tan bien con su entorno como puede mientras sigue confiando en una sintaxis totalmente portátil: solo hace una suposición y es que la $DIRSTACK
variable de entorno es su propiedad para hacer lo que quiera.
Canonicaliza todas las rutas que almacena $DIRSTACK
y las serializa en comillas simples, aunque garantiza que cada una se cite y serialice de forma segura antes de agregarla al valor de la variable y no debería tener ningún problema con ningún carácter especial de ningún tipo . Si se establece la $DIRSTACKMAX
variable de entorno, la usará como límite superior para el número de rutas que conserva en el historial; de lo contrario, el límite es uno.
Si carga la función de la cd
forma habitual, pero también podrá hacer el cd -[num]
retroceso a través de su historial de cambio de directorio.
El mecanismo principal de la función es en cd
sí mismo, y las ${OLD,}PWD
variables de entorno. POSIX especifica que cd
cambien estos para cada movimiento de ruta, por lo que esto solo usa las variables integradas del shell y guarda los valores durante el tiempo que desee.
El script acd_func.sh hace exactamente lo que usted describe. Básicamente, sobrecarga la cd
función y le permite escribir cd --
para obtener una lista de los directorios visitados anteriormente, de los cuales puede seleccionar por número. Me resulta muy difícil usar bash sin esto, y es lo primero que instalo en un nuevo sistema.
Otros ya cubrieron algunas soluciones interesantes. Hace algún tiempo, creé mi propia solución a un problema relacionado que podría modificarse rápidamente para hacer un "historial directo". Básicamente quería "etiquetar" algunos directorios de uso común, y quería que todos los shells abiertos los vieran, y que persistieran entre reinicios.
#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
}
Básicamente, simplemente haría label foo
para llamar al directorio actual foo
, y luego desde cualquier shell, goto foo
debería estar cd
directamente allí. Argumento vacío: label
crearía un objetivo predeterminado para goto
.
No me molesté en implementar la eliminación automática de alias, pero de lo contrario, todavía estoy usando esto en una forma ligeramente modificada.
Puede usar mi función "historial de cd" en http://fex.belwue.de/fstools/bash.html
Recuerda cada directorio donde ha estado y con "cdh" verá una lista de los últimos 9 directorios. Simplemente ingrese el número y regresará a este directorio.
Ejemplo:
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 / hogar / framstag seleccione: 4 framstag @ wupp: / tmp / 135_pana / 1280:
cdh funciona con autocd, también conocido como "cd sin cd": no tiene que escribir cd o pushd.
Me gustaría recomendarle mi función 'cd' extendida:
Proporciona las siguientes características para facilitarle la vida:
para bash , básicamente: en lugar de usar el uso de cd pushd
para cambiar los directores, entonces se guardan (lo que significa apilado)
pushd /home; pushd /var; pushd log
Para ver el uso de la pila dirs
y para una navegación más fácil (para obtener los números de las "entradas de pila", use:
dirs -v
Salida:
me@myhost:/home$ dirs -v
0 /home
1 /var
2 /tmp
Ahora utilice estos números con cd
y ~
como:
cd ~1
Pero ahora estos números se reordenan y la posición "0" cambiará, por lo que solo pushd
el directorio a la posición superior dos veces (o use un ficticio en la posición 0) como:
me@myhost:/home$ dirs -v
0 /home
1 /home
2 /var
3 /tmp
ahora 1..3 mantendrá su posición . Leí esto en alguna parte pero ya no lo sé, así que lo siento por no dar crédito
(para liberar el directorio actual de la pila / eliminarlo del uso del historial popd
)
Consulte la función cdh en "Programación de Shell, 4e" en la página 312. Mantiene el historial en una matriz.
Aquí hay una versión más avanzada: https://drive.google.com/open?id=0B4f-lR6inxQWQ1pPZVpUQ3FSZ2M
Almacena el historial en el archivo CDHISTFILE y permite cambiar al directorio más reciente que contiene una cadena, por ejemplo,
cd -src
Se instala sobre el comando cd existente haciendo un alias cd=_cd
Solo quería agregar marcas fzf como una posible solución.
Una vez instalado, le da a los comandos marcar y saltar para agregar y buscar directorios marcados (sí, no es exactamente el historial completo, solo los que marcó usted mismo).
El problema que tengo con el comportamiento específico de la sesión pushd / popd, es decir, me gustaría tener la misma pila en diferentes sesiones de bash o algo así, que es posible para las marcas fzf.
Intenté la respuesta que dio @mikeserv, pero no funcionó para mí. No sabía cómo solucionarlo, así que escribí el mío:
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[@]}}")
}
Esto también está disponible como GitHub Gist . Para utilizarlo, basta con pegar la función en su .bashrc
o similares, y usted será capaz de hacer cosas como cd -5
ir de nuevo a la 5 ª último directorio que has estado en. cd -h
Le dará una visión general de su historia.