Come invocare esplicitamente una shell integrata?


13

Voglio personalizzare la funzionalità del cdcomando secondo le mie esigenze.

Ho definito la seguente funzione: function cd () { cd "$@" && pushd "$@"; }

L'intento di questa funzione è di spingere automaticamente la directory nello stack in modo che mi risparmi lo sforzo di digitare manualmente pushd .ogni volta.

Tuttavia, la funzione sopra è una funzione infinitamente ricorsiva, poiché la chiamata a cdviene interpretata come la funzione stessa e non cdincorporata.

Come posso fare riferimento al cdbuilt-in in questa funzione?

So che è possibile sfuggire agli alias usando \. Qual è il modo per sfuggire alle funzioni o fare riferimento agli incorporati in un modo più esplicito?

Nota: non voglio rinominare la mia funzione con nient'altro.


3
Perché non solo alias cd=pushd? Cosa ti aspetti che accada quando esegui il cd su qualcosa che non è un percorso assoluto (ad es. cd ../)?
Patrick,

@Patrick pushdnon supporta -P. Ma hai ragione, come mostrato nella domanda, function cdsembra un po 'sbagliato, poiché ha cambiato directory due volte.
Tino,

Risposte:


5

Il commandcomando incorporato impone che un nome di comando venga interpretato come comando incorporato o esterno (saltando alias e ricerca funzioni). È disponibile in tutte le shell POSIX incluso bash.

cd () { command cd "$@" && pushd "$@"; }

(Nota che questo esempio è negativo: non funziona con percorsi relativi e potresti anche digitare pushdil primo posto.)

In bash e zsh (ma non in ksh), puoi usare builtinper forzare l'interpretazione di un nome di comando come incorporato, esclusi alias, funzioni e comandi esterni.


16

Bash ha un comando (incorporato) builtin, che fa esattamente quello che ti serve. La sostituzione cdcon builtin cdnella tua funzione risolverà la ricorsione.


1

Sospetto che quando dici che "non vuoi rinominare la tua funzione con nient'altro", intendi che vuoi poter chiamare la tua funzione con lo stesso nome del comando originale.

Quindi, un altro modo per farlo che funziona anche per cose che non sono integrate, è nominare la tua funzione qualcos'altro e quindi definire un alias per il comando wrapped. Questo funziona perché l'alias non esiste nel contesto di esecuzione della tua funzione.

Esempio wrapper.sh:

#!/bin/bash
function my_wrapper() { wrapped_program $@ && dostuff }

E in, ad esempio, .bash_aliases:

source /path/to/wrapper.sh
alias wrapped_program="my_wrapper"

Ma questo è piuttosto confuso. L'uso commandè preferibile quando possibile.


-1

Affinché ciò funzioni con percorsi relativi, sarebbe necessario quanto segue:

function cd { 
   dir="$(realpath "$@")"
   command cd "$dir"
   pushd "$dir"
}

Questo presuppone che tu sia su una distro Linux abbastanza moderna che contiene l'utilità "realpath". (RHEL 6 non lo fa ad esempio). Se Perl è disponibile, 'realpath' può essere simulato usando:

! realpath $(pwd) > /dev/null 2>&1  && function realpath {
    perl -e "use Cwd realpath; print realpath(\"$1\") . \"\\n\";"
}
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.