Vous pouvez utiliser un ici-doc et. recherchez-le pour un modèle de collecteur général efficace et convivial pour POSIX.
. 8<<-\IOHERE /proc/self/fd/8
command
…
fn() { declaration ; } <<WHATEVER
# though a nested heredoc might be finicky
# about stdin depending on shell
WHATEVER
cat -u ./stdout | ./works.as >> expect.ed
IOHERE
Lorsque vous ouvrez l'hérédoc, vous indiquez au shell un jeton d'entrée IOHERE lui indiquant qu'il doit rediriger son entrée vers le descripteur de fichier que vous spécifiez jusqu'à ce qu'il rencontre l'autre extrémité de votre jeton limiteur. J'ai regardé autour de moi mais je n'ai pas vu beaucoup d'exemples d'utilisation du numéro fd de redirection, comme indiqué ci-dessus en combinaison avec l'opérateur heredoc, bien que son utilisation soit clairement spécifiée dans les instructions de base relatives aux commandes de shell POSIX. La plupart des gens se contentent de pointer stdin et de filmer, mais je trouve que les scriptlets de sourcing de cette façon peuvent empêcher stdin et les applications qui le constituent de se plaindre des chemins d'E / S bloqués.
Le contenu de heredoc est transmis au descripteur de fichier que vous spécifiez, qui est à son tour interprété comme un code shell et exécuté par le. intégré, mais pas sans spécifier un chemin spécifique pour. . Si le chemin / proc / self vous pose problème, essayez / dev / fd / n ou / proc / $$. Cette même méthode fonctionne sur les tuyaux, au fait:
cat ./*.sh | . /dev/stdin
Est probablement au moins aussi imprudent qu'il n'y paraît. Bien sûr, vous pouvez faire la même chose avec sh, mais. Le but de. avec un tuyau anonyme standard.
Quoi qu'il en soit, comme vous l'avez probablement remarqué, je n'ai toujours pas répondu à votre question. Mais si vous y réfléchissez, de la même manière que l'hérédoc transfère l'intégralité de votre code dans.
. 5<<EOIN /dev/fd/5 |\
tee -a ./log.file | cat -u >$(tty)
script
…
more script
EOIN
Ainsi, toute la stdout terminale de tout code exécuté dans votre heredoc est renvoyée. bien sûr et peut facilement être raccordé à un seul tuyau. J'ai inclus l'appel de chat sans tampon parce que je ne connais pas bien la direction actuelle de la sortie standard, mais il est probablement redondant (il est presque certainement tel qu'il est écrit de toute façon) et le pipeline peut probablement se terminer immédiatement.
Vous pouvez également remettre en question la citation manquante de barre oblique inverse dans le deuxième exemple. Cette partie est importante à comprendre avant de vous lancer et peut vous donner quelques idées sur la façon dont elle peut être utilisée. Un limiteur heredoc cité (jusqu'à présent, nous avons utilisé IOHERE et EOIN, et le premier que j'ai cité avec une barre oblique inversée, bien que des guillemets simples ou doubles serviraient le même but) empêchera le shell d'effectuer une expansion des paramètres sur le contenu, mais un limiteur non cité laissera son contenu ouvert à l’extension. Les conséquences de cela quand votre heredoc est. les sources sont dramatiques:
. 3<<HD ${fdpath}/3
: \${vars=$(printf '${var%s=$((%s*2))},' `seq 1 100`)}
HD
echo $vars
> 4,8,12…
echo $var1 $var51
> 4 104
Comme je n'ai pas cité le limiteur heredoc, le shell a élargi le contenu au fur et à mesure de sa lecture et avant de servir le descripteur de fichier résultant. éxécuter. Cela a essentiellement pour résultat que les commandes ont été analysées deux fois - les commandes extensibles de toute façon. Étant donné que je citais le paramètre $ vars comme extension de barre oblique inversée, le shell a ignoré sa déclaration lors de la première passe et n'a supprimé que la barre oblique inverse afin que l'ensemble du contenu développé de printf puisse être évalué par null when. source le script sur la deuxième passe.
Cette fonctionnalité est fondamentalement exactement ce que le shell eval intégré peut fournir, même si la citation est beaucoup plus facile à manipuler dans un heredoc que dans eval, et peut être tout aussi dangereuse. À moins que vous ne planifiiez cela soigneusement, il est probablement préférable de citer le limiteur "EOF" par habitude. Je dis juste.
EDIT: Eh, je regarde cela en arrière et je pense que c'est un peu trop exagéré. Si vous devez TOUT concaténer plusieurs sorties dans un même canal, la méthode la plus simple consiste simplement à utiliser un:
{ or ( command ) list ; } | tee -a ea.sy >>pea.sy
Les curlies tenteront d’exécuter le contenu dans le shell actuel, tandis que les parens seront automatiquement sous-sortis. Néanmoins, tout le monde peut vous dire cela et, du moins à mon avis, le. La solution heredoc constitue une information beaucoup plus précieuse, en particulier si vous souhaitez comprendre le fonctionnement réel du shell.
S'amuser!