También hay $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.
mechalynx
44
@ivy_lynx 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").
Gilles 'SO- deja de ser malvado'
2
¿Hay alguna razón que usas en cd /tmp/dir1; pushd . lugar de solo pushd /tmp/dir1?
GnP
@gnp, no hay razón específica. Fue tomado del enlace al que me he referido en la respuesta. pushd /tmp/dir1debería funcionar bien.
Ramesh
1
Ok, acabo de recoger mi curiosidad. Me gustaría sugerirle que mejore su respuesta con un ejemplo real usando pushdy popdpara recorrer un árbol de directorios de un lado a otro. Tu respuesta ya es la correcta.
GnP
54
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'
OK, no borraré esta respuesta, tal vez sea útil para otros.
jimmij
23
A menos que la pregunta pregunte específicamente bash, esta es una respuesta válida. No lo quites.
liori
¿Qué pasa si el OP edita su pregunta para incluir solo bash, esta respuesta seguirá siendo válida?
Ooker
3
Cabe mencionar que, aparte de 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.
wjv
13
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.
He incluido una referencia de su respuesta. Espero que no te importe. :)
Ramesh
@Ramesh - no, adelante.
slm
8
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).
cd(){["$((${DIRSTACKMAX##*[!0-9]*}0/10))"-gt 0]&&set--"$@""$DIRSTACK"&&
DIRSTACK='pwd -P >&3; command cd'||{ command cd "$@";return;}
_q()whilecase"$1"in(*\'*):;;(*)! DIRSTACK="$DIRSTACK '$2$1'";;esacdoset--"${1#*\'}""$2${1%%\'*}'\''"donewhile["$#"-gt 1]docase ${1:---}in(-|[!-]*|-*[!0-9]*):;;(*)eval" set $((${1#-}+1))"' "${'"$#}\""eval' set -- "$2"'" $2"'
set -- "${'"$1"'}" "$1"';;esac; _q "$1"; shiftdoneeval" 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 aliasesfunction 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_dirlocal cur possib
cur="${COMP_WORDS[COMP_CWORD]}"
possib="${!dir_labels[@]}"
COMPREPLY=( $(compgen -W "${possib}"-- ${cur}))}
complete -F goto_complete gotofunction 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_dirif[ $# -gt 0 ]; then
key="$1"else
key=defaultfi
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_dirif[ $# -gt 0 ]; then
target="$1"else
target="default"fi
dir_labels["$target"]=$PWDfor 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.
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.
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 -v0/home1/var2/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 -v0/home1/home2/var3/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)
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]=$PWDif[[ $1 ==-h ]];thenfor i in ${!cd_history[@]};do
echo $i:"${cd_history[$i]}"donereturnelif[[ $1 =~^-[0-9]+]];then
builtin cd "${cd_history[${1//-}]}"||# Remove the argument's dashreturnelse
builtin cd "$@"||return# Bail if cd failsfi# 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.
Respuestas:
El comando que está buscando es
pushd
ypopd
.Puede ver un ejemplo práctico de trabajo desde
pushd
ypopd
desde aquí .fuente
$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 mencionacd -
cuál es un atajo paracd "$OLDPWD"
).cd /tmp/dir1; pushd .
lugar de solopushd /tmp/dir1
?pushd /tmp/dir1
debería funcionar bien.pushd
ypopd
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 sabercd -2
,cd -4
etc. Es muy convenientecd -
TAB, especialmente con el sistema de terminación y los colores habilitados:Esto es lo que tengo en .zshrc:
Y el resultado:
fuente
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 decd +
ycd -
(una cuestión de gustos),CDABLE_VARS
es irrelevante para las pilas de directorios, y lazstyle
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 conautoload -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 usarpushd
ypopd
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? .
fuente
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).
fuente
Tienes tanta historia como quieras:
Esa es una función de shell que debería permitir que cualquier shell compatible con POSIX ofrezca un historial de
zsh
estilocd
. 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 elcd -[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 quecd
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.fuente
El script acd_func.sh hace exactamente lo que usted describe. Básicamente, sobrecarga la
cd
función y le permite escribircd --
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.fuente
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.
Básicamente, simplemente haría
label foo
para llamar al directorio actualfoo
, y luego desde cualquier shell,goto foo
debería estarcd
directamente allí. Argumento vacío:label
crearía un objetivo predeterminado paragoto
.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.
fuente
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:
cdh funciona con autocd, también conocido como "cd sin cd": no tiene que escribir cd o pushd.
fuente
Me gustaría recomendarle mi función 'cd' extendida:
https://github.com/dczhu/ltcd
Proporciona las siguientes características para facilitarle la vida:
fuente
para bash , básicamente: en lugar de usar el uso de cd
pushd
para cambiar los directores, entonces se guardan (lo que significa apilado)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:Salida:
Ahora utilice estos números con
cd
y~
como: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: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
)fuente
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
fuente
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.
fuente
Intenté la respuesta que dio @mikeserv, pero no funcionó para mí. No sabía cómo solucionarlo, así que escribí el mío:
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 comocd -5
ir de nuevo a la 5 ª último directorio que has estado en.cd -h
Le dará una visión general de su historia.fuente