Bash, benutzerdefiniertes integriertes

Bash, benutzerdefiniertes integriertes

Ich möchte beispielsweise ein benutzerdefiniertes integriertes Element erstellen bash. timeIst das möglich? Wenn nicht, ist es in einer anderen Shell möglich?

Ich möchte beispielsweise Folgendes tun: und es in jedem Verzeichnis innerhalb von CWD map find -name '*.js' | xargs grep func1ausführen lassen . Beachten Sie, dass allesfind -name '*.js' | xargs grep func1einschließlich der Pfeifewird an weitergegeben map.

Das Ziel ist, einen Befehl auf mehrere Verzeichnisse anzuwenden. Ich habe ein Skript namens „ mapwhich evals $1across whatever lsproduced“ geschrieben. Wenn der Befehl, den ich ausführen möchte, jedoch Pipes, Weiterleitungen usw. enthält, muss ich alles innerhalb einer Zeichenfolge in Anführungszeichen setzen. Ich suche nach einer Möglichkeit, dies nicht tun zu müssen.

Außerdem bin ich einfach neugierig, ob das möglich ist ;)

Antwort1

ATT ksh, bash und zsh verfügen jeweils über ein dynamisches Modulladesystem, das das Laden von zusätzlichem Code in eine vorhandene Shell-Instanz ermöglicht, und der dynamisch geladene Code kann neue integrierte Funktionen implementieren. Was Sie verlangen, erfordert jedoch mehr als eine neue integrierte Funktion: Es erfordert eine neue Syntax, und ich glaube, dass keine der Shells damit umgehen kann. Sie müssten den Parser im Quellcode der Shell ändern.

In zsh können Sie der gewünschten Syntax nahe kommen:

for x (*/) (cd $x && pipeline)

Sie können einen Alias ​​erstellen alias map='for x (*/) (cd $x &&', benötigen aber trotzdem die schließende Klammer am Ende. Mit einem groben Hack können Sie genau die gewünschte Syntax erhalten:

alias map='map__PWD=$PWD; for x (./*/ "") cd $map__PWD${x#.}/ && [[ -z $x ]] || '

Das ist so hässlich, fragil und nicht verallgemeinerbar, dass ich es nicht erklären werde. Denken Sie nicht daran, es zu verwenden, wenn Sie nicht vollständig verstehen, wie es funktioniert.

Antwort2

In diesem Fall etwas wie

find . -type f -name "*.js" -exec grep -qF "func1" {} \; -print

würde wahrscheinlich ausreichen, die Namen der *.jsDateien überall im oder unterhalb des aktuellen Verzeichnisses zu finden, die die Zeichenfolge enthalten func1.

Wenn Sie die Dateien vermeiden möchten, die sich im aktuellen Verzeichnis befinden:

find . -mindepth 2 -type f -name "*.js" -exec grep -qF "func1" {} \; -print

Mit -mindepth 2wird findnichts in der „Tiefe 1“, also im aktuellen Verzeichnis, gefunden.

Dieses letzte Element macht im Grunde das, was Sie verlangen. Es wird effektiv grepin jedem Unterverzeichnis des aktuellen Verzeichnisses ausgeführt.

verwandte Informationen