Respostas:
O comando que você está procurando é pushd
e popd
.
Você pode ver um exemplo de trabalho prático pushd
e popd
de aqui .
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
caso de você querer alternar entre dois diretórios usando o mesmo comando, mas não tenho certeza de quão específico é o shell e a distribuição / o kernel.
OLDPWD
existe em todos os shells do POSIX, mas é inútil para esta pergunta que pergunta como ir além disso (a pergunta já menciona cd -
qual é um atalho para cd "$OLDPWD"
).
cd /tmp/dir1; pushd .
vez de apenas pushd /tmp/dir1
?
pushd /tmp/dir1
deve funcionar muito bem.
pushd
e popd
percorrendo uma árvore de diretórios para frente e para trás. Sua resposta já é a correta.
Você não especificou qual shell está usando, portanto, seja uma desculpa para anunciar o zsh.
Sim, temos mais histórico para cd
, ou seja cd -2
, cd -4
etc. Muito conveniente é cd -
TAB, especialmente com o sistema de conclusão e as cores ativadas:
Isto é o que eu tenho no .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 o resultado:
bash
, esta é uma resposta válida. Não o remova.
setopt AUTO_PUSHD
, nenhuma das configurações acima é necessária para obter uma pilha de diretórios onipresente com conclusão no estoque zsh. PUSHD_MINUS
inverte o sentido de cd +
e cd -
(uma questão de gosto), CDABLE_VARS
é irrelevante para as pilhas de diretórios, e a zstyle
invocação fornecida aqui simplesmente adiciona cor à saída de uma conclusão de pilha de diretórios. No entanto, é necessário inicializar o subsistema de conclusão com autoload -U compinit && compinit
.
Para responder sua pergunta sobre "mais histórico". Não, o cd -
recurso no Bash suporta apenas um único diretório para o qual você pode "virar". Como @Ramesh afirma em sua resposta. Se você deseja um histórico mais longo de diretórios, pode usar pushd
e popd
salvar um diretório ou retornar ao anterior.
Você também pode ver a lista do que está atualmente na pilha com o dirs
comando
Uma explicação detalhada pode ser encontrada nesta resposta intitulada: Como uso os comandos pushd e popd? .
Você pode instalar e usar o meu utilitário dirhistory para o bash.
Basicamente, é um daemon que coleta alterações de diretório de todos os seus shells e um programa Cdk que exibe o histórico e permite escolher qualquer diretório para o qual alternar (para que você não fique limitado a uma pilha).
Você tem o histórico que deseja:
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"
}
Essa é uma função do shell que deve permitir que qualquer shell compatível com POSIX ofereça um histórico de zsh
estilo cd
. Ele faz todo o seu trabalho sem invocar um único subshell, e acredito que seu fluxo é bastante sólido - parece tratar todos os casos corretamente sob testes moderados.
A função tenta jogar da melhor maneira possível com o ambiente, enquanto ainda conta com a sintaxe totalmente portátil - faz apenas uma suposição e é que a $DIRSTACK
variável de ambiente é sua propriedade a ser usada da maneira que quiser.
Ele canoniza todos os caminhos que ele armazena $DIRSTACK
e serializa todos eles entre aspas simples - embora garanta que cada um seja citado e serializado com segurança antes de adicioná-lo ao valor da variável e não deve ter nenhum problema com caracteres especiais de qualquer tipo . Se a $DIRSTACKMAX
variável de ambiente estiver configurada, ela será usada como limite superior para o número de caminhos que ela mantém no histórico; caso contrário, o limite é um.
Se você carregar a função da cd
mesma forma normal, mas também poderá fazer isso cd -[num]
para voltar ao histórico do diretório de alterações.
O mecanismo principal da função é cd
ele próprio - e as ${OLD,}PWD
variáveis de ambiente. O POSIX especifica que as cd
altere para cada movimento de caminho - e, portanto, isso apenas usa as variáveis internas do shell e salva os valores pelo tempo que você desejar.
O script acd_func.sh faz exatamente o que você descreve. Essencialmente, ele sobrecarrega a cd
função e permite digitar cd --
para obter uma lista dos diretórios visitados anteriormente, a partir dos quais você pode selecionar por número. Acho muito difícil usar o bash sem isso e é a primeira coisa que instalo em um novo sistema.
Outros já abordaram algumas soluções interessantes. Algum tempo atrás, criei minha própria solução para um problema relacionado que poderia ser modificado rapidamente para criar um "histórico direto". Eu basicamente queria "rotular" alguns diretórios comumente usados e queria que todos os shells abertos os vissem e persistissem entre as reinicializações.
#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
}
Basicamente, eu faria apenas label foo
para chamar o diretório atual foo
e, a partir de qualquer shell, o que goto foo
ocorreria cd
diretamente lá. Argumento vazio: label
criaria um destino padrão para goto
.
Eu não me incomodei em implementar a remoção automática de aliases, mas, caso contrário, ainda estou usando isso de uma forma ligeiramente modificada.
Você pode usar minha função "cd history" em http://fex.belwue.de/fstools/bash.html
Ele lembra todos os diretórios em que você esteve e, com "cdh", você verá uma lista dos últimos 9 diretórios. Basta digitar o número e você estará de volta neste diretório.
Exemplo:
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 selecione: 4 framstag @ wupp: / tmp / 135_pana / 1280:
O cdh funciona com o autocd, também conhecido como "cd sem cd": você não precisa digitar cd ou pushd.
Gostaria de recomendar minha função estendida 'cd' para você:
Ele fornece os seguintes recursos para facilitar a vida:
para o bash , basicamente: em vez de usar o cd pushd
para alterar diretórios, eles são salvos (ou seja, empilhados)
pushd /home; pushd /var; pushd log
Para ver o uso da pilha dirs
e para facilitar a navegação (para obter os números das "entradas da pilha", use:
dirs -v
Resultado:
me@myhost:/home$ dirs -v
0 /home
1 /var
2 /tmp
Agora utilize esses números com cd
e ~
como:
cd ~1
Mas agora esses números são reorganizados agora e a posição "0" será alterada; portanto, apenas pushd
o diretório para a posição superior duas vezes (ou use um manequim na posição 0) como:
me@myhost:/home$ dirs -v
0 /home
1 /home
2 /var
3 /tmp
agora 1..3 vai ficar ai posição eu li isso em algum lugar mas não sei mais, desculpe por não dar crédito
(para liberar o diretório atual da pilha / excluí-lo do uso do histórico popd
)
Veja a função cdh em "Shell Programming, 4e" na página 312. Ele mantém o histórico em uma matriz.
Aqui está uma versão mais avançada: https://drive.google.com/open?id=0B4f-lR6inxQWQ1pPZVpUQ3FSZ2M
Ele armazena o histórico no arquivo CDHISTFILE e permite mudar para o diretório mais recente que contém uma string, por exemplo,
cd -src
Ele se instala sobre o comando cd existente fazendo um alias cd=_cd
Só queria adicionar marcas fzf como uma solução possível.
Uma vez instalado, ele fornece os comandos para marcar e pular para adicionar e procurar diretórios marcados (sim, não é exatamente o histórico completo, apenas os marcados por você).
O problema que tenho com o comportamento específico da sessão pushd / popd it, ou seja, eu gostaria de ter a mesma pilha em diferentes sessões do bash, o que é possível para as marcas fzf.
Tentei a resposta que o @mikeserv deu, mas não funcionou muito para mim. Não consegui descobrir como consertá-lo, então apenas escrevi o meu:
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[@]}}")
}
Isso também está disponível como GistHub Gist . Para usar isso, basta colar a função no seu .bashrc
ou similar, e você poderá fazer coisas como cd -5
voltar ao 5º último diretório em que esteve. cd -h
Fornecerá uma visão geral do seu histórico.