Conflito entre 'pushd'. e 'cd -'

5

Sou um usuário feliz do comando cd - para ir para o diretório anterior. Ao mesmo tempo, gosto de pushd . e popd .

No entanto, quando quero lembrar o diretório de trabalho atual por meio de pushd . , perco a possibilidade de ir para o diretório anterior por cd - . (Como pushd . também executa cd . ).

Como posso usar o pushd para poder usar cd -

?

A propósito: GNU bash, versão 4.1.7 (1)

    
por Bernhard 21.02.2012 / 13:07

3 respostas

7

Você pode usar algo assim:

push() { 
    if [ "$1" = . ]; then
        old=$OLDPWD
        current=$PWD
        builtin pushd .
        cd "$old"
        cd "$current"
    else
        builtin pushd "$1"
    fi
}

Se você nomear pushd , então terá precedência sobre o built-in, já que as funções são avaliadas antes dos built-ins.

Você precisa das variáveis old e current , pois a substituição OLDPWD fará com que perca seu significado especial.

    
por 21.02.2012 / 13:32
3

Uma versão um pouco mais concisa da resposta de Wojtek :

pushd () {
        if [ "$1" = . ]; then
                cd -
                builtin pushd -
        else    
                builtin pushd "$1"
        fi      
}

Ao nomear a função pushd , você pode usar pushd como normal, você não precisa se lembrar de usar o nome da função.

    
por 21.02.2012 / 17:11
0

A resposta de Kevin é excelente. Eu escrevi alguns detalhes sobre o que está acontecendo, caso as pessoas estejam procurando um melhor entendimento de por que seu script é necessário para resolver o problema.

A razão pela qual pushd . quebra o comportamento de cd - será aparente se nos aprofundarmos no funcionamento do cd e da pilha de diretórios. Vamos colocar alguns diretórios na pilha:

$ mkdir dir1 dir2 dir3
$ pushd dir1
~/dir1 ~
$ pushd../dir2
~/dir2 ~/dir1 ~
$ pushd../dir3
~/dir3 ~/dir2 ~/dir1 ~
$ dirs -v
0       ~/dir3
1       ~/dir2
2       ~/dir1
3       ~

Agora, podemos tentar cd - para recuperar um diretório:

$ cd -
/home/username/dir2
$ dirs -v
0       ~/dir2
1       ~/dir2
2       ~/dir1
3       ~

Podemos ver que cd - pulou de volta para o diretório anterior, substituindo stack ~ 0 pelo diretório em que entramos. Podemos voltar com cd - novamente:

$ cd -
/home/username/dir3
$ dirs -v
0       ~/dir3
1       ~/dir2
2       ~/dir1
3       ~

Repare que saltamos de volta para nosso diretório anterior, mesmo que o diretório anterior não tenha sido listado na pilha de diretórios. Isso ocorre porque cd usa a variável de ambiente $OLDPWD para acompanhar o diretório anterior:

$ echo $OLDPWD
/home/username/dir2 

Se fizermos pushd . , enviaremos uma cópia extra do diretório atual para a pilha:

$ pushd . 
~/dir3 ~/dir3 ~/dir2 ~/dir1 ~
$ dirs -v
0       ~/dir3
1       ~/dir3
2       ~/dir2
3       ~/dir1
4       ~

Além de criar uma cópia extra do diretório atual na pilha, pushd . atualizou $OLDPWD :

$echo $OLDPWD
/home/username/dir3

Portanto, cd - perdeu seu histórico útil e, agora, apenas o levará para o diretório atual, sem realizar nada.

    
por 16.12.2016 / 16:42