Ich versuche, xargs zu verwenden, um eine komplexere Funktion parallel aufzurufen.
#!/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 zurück
xargs: echo_var: No such file or directory
Ideen, wie ich xargs verwenden kann, um dies zu erreichen, oder andere Lösungen, wären willkommen.
Antworten:
Das Exportieren der Funktion sollte dies tun (ungetestet):
Sie können das eingebaute
printf
anstelle des externen verwendenseq
:Durch die Verwendung von
return 0
und aufexit 0
diese Weise wird auch jeder Fehlerwert maskiert, der möglicherweise durch den vorhergehenden Befehl erzeugt wird. Wenn es keinen Fehler gibt, ist dies die Standardeinstellung und daher etwas redundant.@phobic erwähnt, dass der Bash-Befehl vereinfacht werden könnte
Bewegen Sie das
{}
direkt hinein. Es ist jedoch anfällig für Befehlsinjektionen, wie von @Sasha hervorgehoben.Hier ist ein Beispiel, warum Sie das eingebettete Format nicht verwenden sollten :
Ein weiteres Beispiel dafür, warum nicht :
Dies wird im sicheren Format ausgegeben :
Dies ist vergleichbar mit der Verwendung parametrisierter SQL- Abfragen , um eine Injektion zu vermeiden .
Ich verwende hier
date
eine Befehlsersetzung oder in Anführungszeichen anstelle desrm
Befehls, der in Sashas Kommentar verwendet wird, da er nicht destruktiv ist.quelle
echo_var
, der eine Funktion in diesem Skript und kein Prozess (Programm) in Ihrem PATH ist. Die Lösung von Dennis besteht darin, die Funktion für untergeordnete Bash-Prozesse zu exportieren, sie dann in den Unterprozess zu verschieben und dort auszuführen._
und\
ohne sie hat es bei mir nicht funktioniert_
) bietet einen Platzhalter fürargv[0]
($0
) und fast alles kann dort verwendet werden. Ich glaube, ich habe das Backslash-Semikolon (\;
) hinzugefügt, weil es zum Beenden der-exec
Klausel in verwendet wirdfind
, aber es funktioniert hier ohne es. Wenn die Funktion$@
stattdessen verwendet$1
würde, würde sie das Semikolon als Parameter sehen, daher sollte es weggelassen werden.bash -c 'echo_var "{}"'
. Sie brauchen also am Ende nicht das _ {}.Die Verwendung von GNU Parallel sieht folgendermaßen aus:
Wenn Sie die Version 20170822 verwenden, müssen Sie dies nicht einmal tun, solange Sie Folgendes ausgeführt
export -f
haben:quelle
sh: parallel_bash_environment: line 67: unexpected EOF while looking for matching
'' sh: parallel_bash_environment: Zeile 79: Syntaxfehler: unerwartetes Dateiende sh: Fehler beim Importieren der Funktionsdefinition fürparallel_bash_environment' /usr/local/bin/bash: parallel_bash_environment: line 67: unexpected EOF while looking for matching
'' / usr / local / bin / bash: parallel_bash_environment: Zeile 79: Syntaxfehler: unerwartetes Ende von file / usr / local / bin / bash: Fehler beim Importieren der Funktionsdefinition für `...So etwas sollte auch funktionieren:
quelle
Möglicherweise ist dies eine schlechte Vorgehensweise, aber wenn Sie Funktionen in einem
.bashrc
oder einem anderen Skript definieren, können Sie die Datei oder zumindest die Funktionsdefinitionen mit der Einstellungallexport
:quelle