Temos mais histórico para cd?

40

cd - pode passar para o último diretório visitado. Podemos visitar mais história que não a última?

    
por Tim 26.09.2014 / 18:07

13 respostas

30

O comando que você está procurando é pushd e popd .

Você pode ver um exemplo prático prático de 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
    
por 26.09.2014 / 18:15
50

Você não especificou qual shell está usando, portanto, deixe que isso 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 sistema de conclusão e cores ativadas:

Isto é o que eu tenho em .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:

    
por 26.09.2014 / 18:44
13

Para responder à sua pergunta sobre "mais histórico". Não, o recurso cd - no Bash suporta apenas um único diretório para o qual você pode "inverter". Como @Ramesh afirma em sua resposta. Se você quiser um histórico mais longo de diretórios, use pushd e popd para salvar um diretório ou retornar a um anterior.

Você também pode ver a lista do que está atualmente na pilha com o comando dirs .

Uma explicação detalhada pode ser encontrada a partir desta resposta intitulada: Como uso os comandos pushd e popd? .

    
por 26.09.2014 / 18:17
8

Você pode instalar e usar meu utilitário dirhistory para bash.

Basicamente, é um daemon que coleta mudanças de diretórios de todos os seus shells, e um programa de Cdk que exibe o histórico e permite escolher qualquer diretório para mudar (assim você não está limitado a uma pilha).

    
por 26.09.2014 / 22:29
6

Você tem o histórico que quiser:

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 de shell que deve permitir que qualquer shell compatível com POSIX ofereça zsh -style cd history. Ele faz todo o seu trabalho sem invocar um único subshell, e eu acredito que seu fluxo é muito bom - parece lidar com todos os casos corretamente sob testes moderados.

A função tenta jogar tão bem com o ambiente quanto possível, embora ainda contando com sintaxe totalmente portátil - faz apenas uma suposição e é que a variável de ambiente $DIRSTACK é sua propriedade para fazer com o que quiser.

Ele canoniza todos os caminhos que ele armazena em $DIRSTACK e serializa todos eles em aspas simples - embora garanta que cada um seja seguramente citado e serializado antes de adicioná-lo ao valor da variável e não deve ter nenhum problema com quaisquer caracteres especiais de qualquer tipo. Se a variável de ambiente $DIRSTACKMAX estiver configurada, ela será usada como um limite superior para o número de caminhos que ela retém no histórico, caso contrário, o limite é um.

Se você carregar a função você apenas cd como normal, mas também poderá fazer o cd -[num] para voltar atrás no histórico do diretório de alterações.

O mecanismo principal da função é cd em si - e as variáveis de ambiente ${OLD,}PWD . O POSIX especifica que cd os altera para cada movimento do caminho - e, portanto, apenas usa as variáveis incorporadas do shell e salva os valores pelo tempo que desejar.

    
por 23.01.2015 / 14:59
4

O script acd_func.sh faz exatamente o que você descreve. Essencialmente, ele sobrecarrega a função cd e permite que você digite cd -- para obter uma lista de diretórios visitados anteriormente, a partir dos quais você pode selecionar por número. Eu acho muito difícil usar o bash sem isso, e é a primeira coisa que eu instalo em um novo sistema.

    
por 08.08.2016 / 23:59
3

Outros já abordaram algumas soluções interessantes. Algum tempo atrás eu criei minha própria solução para um problema relacionado que poderia ser modificado rapidamente para fazer um "histórico direto". Eu basicamente queria "rotular" alguns diretórios comumente usados, e queria que todos os shells abertos os visse, e que eles 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 só faria label foo para chamar o diretório atual foo e, em seguida, de qualquer shell, goto foo whould cd diretamente para lá. Argumento vazio: label criaria um destino padrão para goto .

Não me preocupei em implementar a remoção automática de aliases, mas, por outro lado, ainda estou usando isso de forma ligeiramente modificada.

    
por 23.01.2015 / 16:08
2

Você pode usar minha função "histórico de cd" link

Ele se lembra de todos os diretórios onde você esteve e com "cdh" você verá um lista dos últimos 9 diretórios. Basta digitar o número e você está de volta este 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
select: 4
framstag@wupp:/tmp/135_pana/1280:

cdh trabalha com autocd também conhecido como "cd sem cd": você não precisa digitar cd ou pushd.

    
por 23.12.2016 / 19:24
2

Gostaria de recomendar a minha função 'cd' estendida para você:

link

Eleforneceosseguintesrecursosparafacilitaravida:

  • Listadediretóriosglobais,quemostradiretóriosvisitadosrecentementedetodasasguias/janelasdoterminal.
  • Listadedirlocais,queélocalparaasessãodeshellatual.
  • Asduaslistagenssuportamnavegaçãorápidausandoj/k(descer/subir),númerosepesquisadepalavras.
  • Saltogloballivre(porexemplo,"cd dir" ou "cd ar" para ir para / path / to / foo / bar / directory /).
por 02.04.2017 / 19:59
1

para bash , basicamente: em vez de usar o cd use pushd para alterar as diretórios, para que elas sejam salvas (o que significa que são empilhadas)

pushd /home; pushd /var; pushd log

Para ver a pilha use dirs e para facilitar a navegação (para obter os números do uso de "pilha de entradas":

dirs -v

Saída:

me@myhost:/home$ dirs -v
 0  /home
 1  /var
 2  /tmp

Agora, use esses números com cd e ~ , como:

cd ~1

Mas agora esses números são rearranjados agora e a posição "0" irá mudar, então apenas pushd o diretório para a posição de cima 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 manter a posição Eu li isso em algum lugar, mas não sei mais, então sinto muito por não dar crédito

(para liberar o diretório atual da pilha / excluí-lo do histórico use popd )

    
por 15.12.2016 / 13:11
1

Veja a função cdh em "Programação Shell, 4e" na página 312. Ele mantém o histórico em uma matriz.

Aqui está uma versão mais avançada: link

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

    
por 17.08.2017 / 05:25
1

Só queria adicionar fzf-marks como uma possível solução.

Uma vez instalado, você recebe os comandos mark e jump para adicionar e pesquisar diretórios favoritos (sim, o histórico não é exatamente o completo, apenas os que você marcou como favorito) você mesmo).

O problema que tenho com pushd / popd é o comportamento específico da sessão, ou seja, eu gostaria de ter a mesma pilha em uma sessão bash diferente ou assim que é possível para fzf-marks.

    
por 28.03.2018 / 11:16
0

Eu tentei a resposta que @ mikeserv deu, mas não funcionou bem para mim. Eu não consegui descobrir como corrigi-lo, então eu 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 GitHub Gist . Para usar isso, apenas cole a função em seu .bashrc ou similar, e você poderá fazer coisas como cd -5 para voltar para o último diretório em que você esteve . cd -h lhe dará uma visão geral do seu histórico.

    
por 25.02.2018 / 02:29