É possível substituir o comando "cd" incorporado na linha de comando?


22

Sempre que eu 'cd' em um diretório diferente na minha máquina (nesse caso, executando o Mac OS X 10.6.7) pela linha de comando (que é o bash), eu imediatamente digito 'ls' para obter a lista de conteúdos nesse diretório. Estou tentando descobrir uma maneira de substituir o 'cd' para que ele mude para o diretório solicitado e depois me dê a lista de uma só vez.

Consegui obter a funcionalidade básica que estou procurando trabalhar com a seguinte linha adicionada ao meu ~ / .bash_profile

function cl() { cd "$@"; ls -l; }

Isso funciona conforme o esperado. Mudando para o diretório solicitado e depois me mostrando o conteúdo. Onde encontro um problema é tentar substituir o próprio "cd" em vez de criar um novo comando "cl".

O seguinte não funciona

##### Attempt 1 #####
# Hangs the command line

function cd() { cd "$@"; ls -l; }


##### Attempt 2 #####
# Hangs the command line

function cd() { 'cd' "$@"; ls -l; }


##### Attempt 3 #####
# Does not change directory. 
# Does list contents, but of the directory where you started.

function cd() { /usr/bin/cd "$@"; ls -l; }


#### Other attempts that fail in various ways #####
alias cd=cd "$@"; ls -la;
alias cd="cd '$@'; ls -la;"
alias cd='cd "$@"'; ls -la;
alias cd=/usr/bin/cd "$@"; ls -la;

Também tentei várias outras iterações que não estão listadas, além de criar um alias que aponta para a função 'cl' em funcionamento. Nenhum dos quais funcionou.

O que li na documentação fala sobre o fato de que 'cd' não pode ser executado como um comando externo (que é o que eu entendo ser o modo como a função precisaria usá-lo).

Portanto, atualmente posso usar meu comando "cl" e obter o que quero, mas a questão é / permanece:

Existe uma maneira de substituir o comportamento do 'cd' para que ele mude para o diretório solicitado e faça outra coisa depois?

Respostas:


30

O seguinte deve funcionar:

function cd() { builtin cd "$@" && ls -l; }

Como a função está em uma única linha, assegure-se de que ela seja finalizada ;como acima para funcionar corretamente.


Não funciona para uma chamada sem parâmetros.
Daniel Beck

3
@ DanielBeck - pelo menos no meu Mac OSX (10.6.7), isso está funcionando bem com uma chamada sem parâmetros. O comportamento é que ele muda para o diretório inicial e, em seguida, faz a lista desse diretório. Duplicar efetivamente a funcionalidade do 'cd' comum com o novo recurso adicionado no final.
Alan W. Smith

2
@ Alan True, eu testei isso escrevendo esse código ad-hoc no shell. Parece que o comportamento de cd ""(o que esta resposta deve avaliar é diferente cd "$@"com vazio $@Desculpe a confusão..
Daniel Beck

@DanielBeck - não se preocupe.
Alan W. Smith

2
Nota: estou mudando isso para a resposta aceita, pois é uma resposta precisa à pergunta. O de @RichHomolka é ótimo para abordar o principal, mas este é exatamente o que pode ser colocado no seu arquivo ~ / .bash_profile.
Alan W. Smith

10

Eu acho que você está correndo em um loop. Sua cdfunção está chamando cd, que é ... a função.

Você precisa saber sobre builtinqual é uma palavra-chave que faz com que a pesquisa de comando use os recursos internos do Bash, como cd, e não sua função

function cd
{
    builtin cd "$1"
    : do something else
}

Além disso, a chamada /usr/bin/cdnunca funcionará, mesmo que esse comando existisse.

O que aconteceria:

  • Meu Bash shell está em dir /bash/dir.
  • Eu executo um comando /usr/bin/cd /dir/for/cd.
  • /usr/bin/cdvai para dir /dir/for/cd.
  • /usr/bin/cd saídas.
  • O Bash ainda está ativo /bash/dir, porque o processo filho /usr/bin/cdnão pode afetar o pai.

Os aliases também são simples substituições de texto. Eles nunca podem ter parâmetros.


Eu sugiro builtin cd $@ && ls; uma vez que a cdchamada deve ter sucesso para que todo o resto faça sentido. Além disso, lembre-se de casos especiais como cd(sem argumento).
Daniel Beck

Nota: Tentei marcar isso como a resposta aceita, mas está me dizendo que tenho que esperar mais 6 minutos antes de poder fazer isso. Não sabia que havia um atraso incorporado antes que você pudesse fazer isso.
Alan W. Smith

@ Alan Outra solução melhor pode surgir em um prazo bastante razoável (ou seja, nos poucos minutos que você precisa esperar). Eu acho que é por isso que existe um atraso exigido pelo sistema: você deve preferir qualidade ao invés de velocidade. Não deve ser muito inconveniente.
Daniel Beck

E nós temos um vencedor. Isso funciona como um campeão. Por @DanielBeck, mudei para usar o && e o condensou em uma linha com: function cd {cd incorporado "$ @" && ls -l; }
Alan W. Smith

@DanielBeck - Sim, eu não estou preocupado com isso. Só nunca percebi isso antes. Eu posso ver a lógica, apenas me surpreendeu um pouco.
Alan W. Smith

6

Sugiro não substituir o cd porque existem outros scripts que seqüestram a função 'cd', por exemplo, rvm. Seria melhor escolher outro nome, como 'd', e não especificar o tipo 'builtin' na sua função; caso contrário, o seqüestrador não funcionaria. Estou usando o código abaixo:

function d() { cd "$@" && ls;} 

Eu pensei que isso não funcionaria, de acordo com a pergunta do OP.
User305964
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.