fonctions lambda dans bash
Existe-t-il un moyen d'implémenter/utiliser des fonctions lambda dans bash? Je pense à quelque chose comme:
$ someCommand | xargs -L1 (lambda function)
5 réponses
Je ne connais pas de moyen de le faire, mais vous pourrez peut-être accomplir ce que vous essayez de faire en utilisant:
somecommand | while read -r; do echo "Something with $REPLY"; done
Ce sera également plus rapide, car vous ne créerez pas de nouveau processus pour chaque ligne de texte.
[modifier 2009-07-09] J'ai fait deux changements:
- a incorporé la suggestion de litb d'utiliser
-r
pour désactiver le traitement des barres obliques inverses - cela signifie que les barres obliques inverses dans l'entrée seront transmises inchangées. - au lieu de fournir un nom de la variable (comme
X
) en tant que paramètre àread
, nous laissonsread
affecter à sa variable par défaut,REPLY
. Cela a l'effet secondaire agréable de préserver les espaces avant et arrière, qui sont dépouillés autrement (même si les espaces internes sont préservés).
D'après mes observations, ensemble ces changements préservent tout sauf les caractères NUL (ASCII 0) littéraux sur chaque ligne d'entrée.
[MODIFIER 26/7/2016]
Selon commentateur Evi1M4chine, définir $IFS
sur la chaîne vide avant d'exécuter read X
(par exemple, avec la commande IFS='' read X
) devrait également préserver les espaces au début et à la fin lors du stockage du résultat dans $X
, ce qui signifie que vous n'êtes pas obligé d'utiliser $REPLY
.
Si vous voulez de vraies fonctions, et pas seulement des pipes ou des boucles while (par exemple si vous voulez les passer, comme s'il s'agissait de données), Je ne ferais tout simplement pas de lambdas, et définirais des fonctions fictives avec un nom fictif récurrent, à utiliser tout de suite, et jeter après. Comme ça:
# An example map function, to use in the example below.
map() { local f="$1"; shift; for i in "$@"; do "$f" "$i"; done; }
# Lambda function [λ], passed to the map function.
λ(){ echo "Lambda sees $1"; }; map λ *
Comme dans les langages fonctionnels appropriés, il n'est pas nécessaire de passer des paramètres, car vous pouvez les envelopper dans une fermeture:
# Let’s say you have a function with three parameters
# that you want to use as a lambda:
# (As in: Partial function application.)
trio(){ echo "$1 Lambda sees $3 $2"; }
# And there are two values that you want to use to parametrize a
# function that shall be your lambda.
pre="<<<"
post=">>>"
# Then you’d just wrap them in a closure, and be done with it:
λ(){ trio "$pre" "$post" "$@"; }; map λ *
Je dirais que c'est encore plus court que toutes les autres solutions présentées ici.
Si vous ne voulez que xargs (option parallèle -P N
par exemple), et seulement bash comme code de fonction, alors bash -c
peut être utilisé comme paramètre pour xargs.
seq 1 10 | tr '\n' '\0' | xargs -0 -n 1 bash -c 'echo any bash code $0'
Les options Tr et -0 sont utilisées ici pour désactiver les substitutions de paramètres xargs.
Oui. On peut passer autour d'une variable de chaîne représentant un appel de commande, puis exécuter la commande avec eval.
Exemple:
command='echo howdy'
eval "$command"