È possibile sovrascrivere il comando "cd" incorporato nella riga di comando?


22

Quasi ogni volta che 'cd' in una directory diversa sulla mia macchina (in questo caso, eseguendo Mac OS X 10.6.7) tramite la riga di comando (che è bash), digito immediatamente 'ls' per ottenere l'elenco dei contenuti in quella directory. Sto cercando di trovare un modo per sovrascrivere 'cd' in modo che cambi nella directory richiesta e poi mi dia l'elenco in un colpo solo.

Sono stato in grado di ottenere le funzionalità di base che sto cercando di lavorare con la seguente riga aggiunta al mio ~ / .bash_profile

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

Funziona come previsto. Passare alla directory richiesta e quindi mostrarmi i contenuti. Il punto in cui mi imbatto in un problema sta cercando di sovrascrivere "cd" stesso invece di creare un nuovo comando "cl".

Le seguenti cose non funzionano

##### 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;

Ho anche provato diverse altre iterazioni che non sono elencate, oltre a creare un alias che punta alla funzione 'cl' funzionante. Nessuno dei quali ha funzionato.

Quello che ho letto nella documentazione parla del fatto che 'cd' non può essere eseguito come comando esterno (che è quello che ho capito essere il modo in cui la funzione avrebbe bisogno di usarlo).

Quindi, attualmente posso usare il mio comando "cl" e ottenere ciò che voglio, ma la domanda è / rimane:

C'è un modo per sovrascrivere il comportamento di 'cd' per farlo cambiare nella directory richiesta e poi fare qualcos'altro in seguito?

Risposte:


30

Il seguente dovrebbe funzionare:

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

Poiché la funzione è su una sola riga, assicurarsi che sia terminata ;come sopra per funzionare correttamente.


Non funziona per una chiamata senza parametri.
Daniel Beck

3
@DanielBeck - almeno sul mio Mac OSX (10.6.7) funziona perfettamente con una chiamata senza parametri. Il comportamento è che cambia nella home directory e quindi fa l'elenco di quella directory. Duplicare efficacemente la funzionalità di un vecchio cd con la nuova funzionalità aggiunta alla fine.
Alan W. Smith,

2
@Alan Vero, l'ho provato scrivendo quel codice ad hoc nella shell. Sembra che il comportamento di cd ""(rispetto a ciò che questa risposta dovrebbe valutare sia diverso da cd "$@"vuoto $@. Mi dispiace per la confusione.
Daniel Beck

@DanielBeck - nessuna preoccupazione.
Alan W. Smith,

2
Nota: sto cambiando questo per la risposta accettata poiché è una risposta precisa alla domanda. Quello di @RichHomolka è ottimo per indirizzare il principale, ma questo è esattamente ciò che può essere inserito nel tuo file ~ / .bash_profile.
Alan W. Smith,

10

Penso che stai correndo in un ciclo. La tua cdfunzione sta chiamando cd, che è ... la funzione.

Devi sapere builtinquale è una parola chiave che fa sì che la ricerca dei comandi usi i builtin di Bash come cd e non la tua funzione

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

Inoltre, la chiamata /usr/bin/cdnon funzionerà mai, anche se esistesse un tale comando.

Cosa succederebbe:

  • La mia shell Bash è in dir /bash/dir.
  • Eseguo un comando /usr/bin/cd /dir/for/cd.
  • /usr/bin/cdva a dir /dir/for/cd.
  • /usr/bin/cd uscite.
  • Bash è ancora attivo /bash/dirperché il processo figlio /usr/bin/cdnon può influire sul genitore.

Anche gli alias sono semplici sostituzioni di testo. Non possono mai avere parametri.


Io suggerisco builtin cd $@ && ls; poiché la cdchiamata dovrebbe avere esito positivo per tutto il resto. Inoltre, ricorda casi speciali come cd(nessun argomento).
Daniel Beck

Nota a margine: ho provato a contrassegnare questa come risposta accettata, ma mi sta dicendo che devo aspettare altri 6 minuti prima di poterlo fare. Non sapevo che ci fosse un ritardo incorporato prima che tu potessi farlo.
Alan W. Smith,

@Alan Un'altra soluzione migliore potrebbe arrivare in un lasso di tempo molto ragionevole (cioè quei pochi minuti che devi aspettare). Immagino sia per questo che c'è un ritardo obbligatorio del sistema: dovresti preferire la qualità alla velocità. Non dovrebbe essere troppo un inconveniente.
Daniel Beck

E abbiamo un vincitore. Funziona come un campione. Per @DanielBeck, ho cambiato per usare && e lo ho condensato su una riga con: funzione cd {cd incorporato "$ @" && ls -l; }
Alan W. Smith,

@DanielBeck - Sì, non mi preoccupo. Non l'ho mai notato prima. Riesco a vedere la logica in esso, mi ha solo sorpreso un po '.
Alan W. Smith,

6

Suggerisco di non sovrascrivere il cd perché ci sono altri script che dirottano la funzione 'cd', ad esempio rvm. Sarebbe meglio scegliere un altro nome, come 'd', invece e non specificare il tipo 'incorporato' nella tua funzione; altrimenti, il dirottatore non funzionerebbe. Sto usando il codice qui sotto:

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

Pensavo che non avrebbe funzionato, però, per la domanda del PO.
user305964,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.