Principe de la file d’attente
Le script définit queue_start qui crée un répertoire temporaire via mktemp -d puis un FIFO avec mkfifo. Le FIFO sert de canal de communication entre le processus appelant et xargs, qui lit les commandes séparées par le caractère NUL (-0) et les exécute en parallèle grâce à l’option -P. Le nombre de processus simultanés est limité par le paramètre fourni à queue_start, garantissant que la charge ne dépasse pas la capacité souhaitée.
Gestion des descripteurs et des signaux
Le script recherche le premier descripteur de fichier libre entre 3 et 9 (plage imposée par Zsh) afin d’éviter les conflits avec les descripteurs standards. Ce descripteur est redirigé vers stderr (exec ${fd}>&2) pour que xargs puisse récupérer les messages d’erreur tout en conservant la sortie standard séparée. Des traps sont installés (trap _queue_stop EXIT, trap 'exit 129' HUP, etc.) pour garantir que les processus enfants sont terminés proprement, même lorsque le shell n’est pas interactif.
Soumission et terminaison des tâches
queue_submit() {
if [[ -z ${_queue_fd:-} ]]; then
echo "queue_submit: no command queue started" >&2
return 1
fi
env printf '%s\0' "$1" >&"${_queue_fd}" &
wait "$!"
}Chaque appel à queue_submit écrit la commande dans le FIFO en utilisant printf avec le séparateur NUL. En mode interactif, l’écriture se fait au premier plan pour éviter que les traps SIGTERM/SIGHUP/INT soient retardés ; en mode non‑interactif, l’écriture s’effectue en arrière‑plan afin que la file pleine n’interrompe pas le traitement des signaux. La fonction queue_wait ferme le descripteur d’écriture, attend que le processus xargs se termine (boucle kill -0) puis libère les variables internes.
Analyse des contraintes et limites
Le mécanisme repose sur xargs -P, qui n’est pas disponible sur toutes les implémentations (par exemple, certaines versions de BusyBox). De plus, la recherche de descripteurs libres se limite à 3‑9, ce qui peut échouer dans des environnements où ces descripteurs sont déjà occupés, entraînant l’erreur « no free fd from 3 to 9 ». Le script ne gère pas les codes de sortie supérieurs à 255 ; tout code non nul est forcé à 1 pour éviter que xargs s’arrête prématurément, ce qui masque la nature exacte de l’échec. Enfin, la dépendance à mkfifo et aux signaux POSIX rend le script sensible aux variations de comportement entre Bash et Zsh, bien que les tests indiquent une compatibilité fonctionnelle.
En pratique, le modèle permet d’accélérer des tâches I/O‑bound comme des appels curl parallèles, tout en conservant un contrôle strict du nombre de processus actifs. La séparation de la sortie standard et de l’erreur via le FIFO évite le mélange de flux, facilitant le post‑traitement (ex. jq). Cependant, pour des charges CPU‑intensives ou des exigences de fiabilité élevées, il reste recommandé d’utiliser un langage disposant d’un vrai pool de threads (Python, Go, Rust), car le script Bash ne peut pas garantir l’isolation complète des erreurs ni la récupération automatique des tâches échouées.