2012-06-12 8 views
92

Ich versuche, Xargs zu verwenden, um eine komplexere Funktion parallel aufzurufen.Shell-Funktionen mit Xargs aufrufen

#!/bin/bash 
echo_var(){ 
    echo $1 
    return 0 
} 
seq -f "n%04g" 1 100 |xargs -n 1 -P 10 -i echo_var {} 
exit 0 

Dies gibt den Fehler

xargs: echo_var: No such file or directory 

Irgendwelche Ideen auf, wie ich xargs dies tun kann, oder jede andere Lösung (en) wäre willkommen.

+1

Gefahr, user1148366, Gefahr! Verwenden Sie keine bash für die parallele Programmierung - Sie werden so viele Probleme haben. Verwenden Sie C/C++ und Pthreads, oder Java-Threads, oder irgendetwas, was Sie lange darüber nachdenken lässt, was Sie tun, weil paralleles Programmieren viele Gedanken benötigt, um richtig zu machen. –

+17

@DavidSouther Wenn die Aufgaben unabhängig sind, z. B. alle diese Bilddateien in PNG konvertieren, dann mach dir keine Sorgen. Es ist, wenn Sie Synchronisation haben (darüber hinaus warten, bis alle fertig sind) und Kommunikation, dass es unordentlich wird. –

Antwort

87

die Funktion Exportieren sollte es tun (ungetestet):

export -f echo_var 
seq -f "n%04g" 1 100 | xargs -n 1 -P 10 -I {} bash -c 'echo_var "[email protected]"' _ {} 

Sie können die eingebauten printf anstelle des externen seq verwenden:

printf "n%04g\n" {1..100} | xargs -n 1 -P 10 -I {} bash -c 'echo_var "[email protected]"' _ {} 

Auch return 0 und exit 0 wie unter Verwendung der Masken jeder Fehlerwert, der von dem ihm vorausgehenden Befehl erzeugt werden könnte. Auch wenn es keinen Fehler gibt, ist es der Standard und somit etwas redundant.

+7

Ein bisschen mehr Diskussion: xargs führt eine komplett neue Instanz des genannten Prozesses aus. In diesem Fall geben Sie den Namen "echo_var" an, bei dem es sich um eine Funktion in diesem Skript handelt, und nicht um einen Prozess (ein Programm) in Ihrem PATH. Die Lösung von Dennis besteht darin, die Funktion für untergeordnete Bash-Prozesse zu exportieren, die dann zum Unterprozess verzweigt und dort ausgeführt wird. –

+4

Was ist die Bedeutung von '_' und' '' ', ohne sie funktionierte es nicht für mich – Hashbrown

+6

@Hashbrown: Der Unterstrich (' _') bietet einen Platzhalter für 'argv [0]' ('$ 0 ') und fast alles könnte dort verwendet werden. Ich denke, ich habe das Backslash-Semikolon ('\;') wegen seiner Verwendung beim Beenden der '-exec'-Klausel in 'find' hinzugefügt, aber es funktioniert für mich ohne es hier. Wenn die Funktion '$ @' anstelle von '$ 1' verwenden würde, würde das Semikolon als Parameter angezeigt. Daher sollte es weggelassen werden. –

12

Parallel GNU Verwendung ist wie folgt aussieht:

#!/bin/bash 
echo_var(){ 
    echo $1 
    return 0 
} 
export -f echo_var 
seq -f "n%04g" 1 100 | parallel -P 10 echo_var {} 
exit 0 

Wenn Sie Version 20170822 Sie haben nicht einmal zu export -f haben, solange Sie dies ausgeführt haben:

. `which env_parallel.bash` 
seq -f "n%04g" 1 100 | env_parallel -P 10 echo_var {} 
+0

Wo bekomme ich Shop für osx? parallel_bash_environment: Linie 67: unerwartetes EOF bei der Suche nach passenden ' '' sh: parallel_bash_environment: Linie 79: Syntaxfehler: unerwartetes Ende der Datei sh: – Nick

+0

NVM es in zsh – Nick

+0

bekommen diese unter eError Ole ' sh setopt wird Fehler Funktionsdefinition für 'parallel_bash_environment' importieren /usr/local/bin/bash: parallele_bash_environment: Zeile 67: Unerwarteter EOF beim Suchen nach passendem ''' /usr/local/bin/bash: parallele_bash_umgebung: Zeile 79: Syntaxfehler: unerwartet Ende der Datei /usr/local/bin/bash: Fehler beim Import der Funktionsdefinition für '... – Nick

5

So etwas sollte arbeiten auch:

function testing() { sleep $1 ; } 
echo {1..10} | xargs -n 1 | xargs [email protected] -P4 bash -c "$(declare -f testing) ; testing @ ; echo @ " 
0

Vielleicht ist dies eine schlechte Praxis, aber Sie, wenn Sie definitiv sind Funktionen in einem .bashrc oder anderen Skript ing, können Sie die Funktionsdefinitionen, die Datei oder zumindest mit einer Einstellung von allexport wickeln:

set -o allexport 

function funcy_town { 
    echo 'this is a function' 
} 
function func_rock { 
    echo 'this is a function, but different' 
} 
function cyber_func { 
    echo 'this function does important things' 
} 
function the_man_from_funcle { 
    echo 'not gonna lie' 
} 
function funcle_wiggly { 
    echo 'at this point I\'m doing it for the funny names' 
} 
function extreme_function { 
    echo 'goodbye' 
} 

set +o allexport