Respuestas:
El comando que está buscando es pushdy popd.
Puede ver un ejemplo práctico de trabajo desde pushdy popddesde 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
$OLDPWDen 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.
OLDPWDexiste 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/dir1debería funcionar bien.
pushdy popdpara 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 -4etc. 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_MINUSinvierte el sentido de cd +y cd -(una cuestión de gustos), CDABLE_VARSes irrelevante para las pilas de directorios, y la zstyleinvocació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 pushdy popdguardar un directorio o volver a uno anterior.
También puede ver la lista de lo que está actualmente en la pila con el dirscomando.
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 zshestilo 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 $DIRSTACKvariable de entorno es su propiedad para hacer lo que quiera.
Canonicaliza todas las rutas que almacena $DIRSTACKy 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 $DIRSTACKMAXvariable 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 cdforma 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 cdsí mismo, y las ${OLD,}PWDvariables de entorno. POSIX especifica que cdcambien 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 cdfunció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 foopara llamar al directorio actual foo, y luego desde cualquier shell, goto foodebería estar cddirectamente allí. Argumento vacío: labelcrearí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 pushdpara cambiar los directores, entonces se guardan (lo que significa apilado)
pushd /home; pushd /var; pushd log
Para ver el uso de la pila dirsy 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 cdy ~como:
cd ~1
Pero ahora estos números se reordenan y la posición "0" cambiará, por lo que solo pushdel 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 .bashrco similares, y usted será capaz de hacer cosas como cd -5ir de nuevo a la 5 ª último directorio que has estado en. cd -hLe dará una visión general de su historia.