GNU/Linux >> Tutoriels Linux >  >> Linux

Apprenez les scripts Bash multi-threading avec GNU Parallel

Si vous en avez assez que vos scripts Bash prennent une éternité à s'exécuter, ce tutoriel est fait pour vous. Souvent, vous pouvez exécuter des scripts Bash en parallèle, ce qui peut considérablement accélérer le résultat. Comment? Utilisation de l'utilitaire GNU Parallel, également appelé Parallel, avec quelques exemples pratiques de GNU Parallel !

Parallel exécute des scripts Bash en parallèle via un concept appelé multi-threading. Cet utilitaire vous permet d'exécuter différentes tâches par CPU au lieu d'une seule, réduisant ainsi le temps d'exécution d'un script.

Dans ce didacticiel, vous allez apprendre les scripts Bash multi-threading avec une tonne d'excellents exemples GNU Parallel !

Prérequis

Ce tutoriel sera plein de démonstrations pratiques. Si vous avez l'intention de suivre, assurez-vous d'avoir les éléments suivants :

  • Un ordinateur Linux. N'importe quelle distribution fonctionnera. Le didacticiel utilise Ubuntu 20.04 exécuté sur le sous-système Windows pour Linux (WSL).
  • Connecté avec un utilisateur disposant des privilèges sudo.

Installation de GNU Parallel

Pour commencer à accélérer les scripts Bash avec le multithreading, vous devez d'abord installer Parallel. Commençons donc par le télécharger et l'installer.

1. Ouvrez un terminal Bash.

2. Exécutez wget pour télécharger le package Parallèle. La commande ci-dessous télécharge la dernière version (parallel-latest ) dans le répertoire de travail courant.

wget https://ftp.gnu.org/gnu/parallel/parallel-latest.tar.bz2

Si vous préférez utiliser une ancienne version de GNU Parallel, vous pouvez trouver tous les packages sur le site de téléchargement officiel.

3. Maintenant, exécutez la commande tar ci-dessous pour désarchiver le package que vous venez de télécharger.

Ci-dessous, la commande utilise le x drapeau pour extraire l'archive, j pour préciser qu'il cible une archive avec un .bz2 extension, et f pour accepter un fichier comme entrée de la commande tar. sudo tar -xjf parallel-latest.tar.bz2

sudo tar -xjf parallel-latest.tar.bz2

Vous devriez maintenant avoir un répertoire nommé parallel- avec le mois, le jour et l'année de la dernière version.

4. Naviguez dans le dossier d'archive du package avec cd . Dans ce didacticiel, le dossier d'archive du package s'appelle parallel-20210422 , comme indiqué ci-dessous.

5. Ensuite, construisez et installez le binaire GNU Parallel en exécutant les commandes suivantes :

./configure
 make
 make install

Maintenant, vérifiez que Parallel est correctement installé en vérifiant la version installée.

parallel --version

Lorsque vous exécutez Parallel pour la première fois, vous pouvez également voir quelques lignes effrayantes qui affichent du texte comme perl: warning: . Ces messages d'avertissement indiquent que Parallel ne peut pas détecter vos paramètres régionaux et linguistiques actuels. Mais ne vous inquiétez pas de ces avertissements pour le moment. Vous apprendrez comment corriger ces avertissements plus tard.

Configurer GNU parallèle

Maintenant que Parallel est installé, vous pouvez l'utiliser tout de suite ! Mais d'abord, il est important de configurer quelques paramètres mineurs avant de commencer.

Toujours dans votre terminal Bash, acceptez l'autorisation de recherche universitaire GNU Parallel indiquant à Parallel que vous le citerez dans toute recherche universitaire en spécifiant le citation paramètre suivi de will cite .

Si vous ne souhaitez pas soutenir GNU ou ses responsables, il n'est pas nécessaire d'accepter de citer pour utiliser GNU Parallel.

parallel --citation
will cite

Modifiez les paramètres régionaux en définissant les variables d'environnement suivantes en exécutant les lignes de code ci-dessous. La définition de variables d'environnement locales et linguistiques comme celle-ci n'est pas une exigence. Mais GNU Parallel les vérifie à chaque fois qu'il s'exécute.

Si les variables d'environnement n'existent pas, Parallel s'en plaindra à chaque fois comme vous l'avez vu dans la section précédente.

Ce didacticiel suppose que vous êtes anglophone. D'autres langues sont également prises en charge.

export LC_ALL=C man
export LANGUAGE=en_US
export LANG=en_US.UTF-8

Exécuter des commandes shell ad hoc

Commençons maintenant à utiliser GNU Parallel ! Pour commencer, vous apprendrez la syntaxe de base. Une fois que vous serez à l'aise avec la syntaxe, vous aborderez plus tard quelques exemples pratiques de GNU Parallel.

Pour commencer, couvrons un exemple super simple de faire écho aux chiffres 1-5.

1. Dans votre terminal Bash, exécutez les commandes suivantes. Excitant, non ? Bash utilise la commande echo pour envoyer les nombres 1-5 au terminal. Si vous mettiez chacune de ces commandes dans un script, Bash les exécuterait séquentiellement, attendant que la précédente se termine.

Dans cet exemple, vous exécutez cinq commandes qui ne prennent pratiquement pas de temps. Mais, imaginez si ces commandes étaient des scripts Bash qui faisaient réellement quelque chose d'utile mais qui prenaient une éternité à s'exécuter ?

 echo 1
 echo 2
 echo 3
 echo 4
 echo 5

Maintenant, exécutez chacune de ces commandes en même temps avec Parallel comme ci-dessous. Dans cet exemple, Parallel exécute la commande echo et désigné par le ::: , passe cette commande les arguments, 1 , 2 , 3 , 4 , 5 . Les trois points indiquent à Parallel que vous fournissez une entrée via la ligne de commande plutôt que le pipeline (plus tard).

Dans l'exemple ci-dessous, vous avez passé une seule commande à Parallel sans options. Ici, comme tous les exemples parallèles, Parallel a démarré un nouveau processus pour chaque commande en utilisant un cœur de processeur différent.

# From the command line
 parallel echo ::: 1 2 3 4 5

Toutes les commandes parallèles suivent la syntaxe parallel [Options] .

3. Pour illustrer la réception parallèle des entrées du pipeline Bash, créez un fichier appelé count_file.txt comme ci-dessous. Chaque nombre représente l'argument que vous passerez à la commande echo.

 1
 2
 3
 4
 5

4. Maintenant, exécutez le cat commande pour lire ce fichier et transmettre la sortie à Parallel, comme indiqué ci-dessous. Dans cet exemple, le {} représente chaque argument (1-5) qui sera passé à Parallel.

# From the pipeline cat count_file.txt | parallel echo {}

Comparaison de Bash et GNU Parallel

À l'heure actuelle, l'utilisation de Parallel peut sembler être une manière compliquée d'exécuter des commandes Bash. Mais le véritable avantage pour vous est le gain de temps. N'oubliez pas que Bash fonctionnera sur un seul cœur de processeur tandis que GNU Parallel fonctionnera sur plusieurs à la fois.

1. Pour démontrer la différence entre les commandes séquentielles Bash et Parallel, créez un script Bash appelé test.sh avec le code suivant. Créez ce script dans le même répertoire que vous avez créé le count_file.txt en plus tôt.

Le script Bash ci-dessous lit le count_file.txt fichier, dort pendant 1, 2, 3, 4 et 5 secondes, renvoie la durée de veille au terminal et se termine.

#!/bin/bash
 nums=$(cat count_file.txt) # Read count_file.txt
 for num in $nums           # For each line in the file, start a loop
 do
     sleep $num             # Read the line and wait that many seconds
     echo $num              # Print the line
 done

2. Maintenant, exécutez le script en utilisant le time commande pour mesurer combien de temps le script prend pour se terminer. Cela prendra 15 secondes.

time ./test.sh

3. Maintenant, utilisez le time commande à nouveau pour effectuer la même tâche, mais cette fois, utilisez Parallel pour le faire.

La commande ci-dessous effectue la même tâche mais cette fois, au lieu d'attendre la fin de la première boucle avant de démarrer la suivante, elle en exécutera une sur chaque cœur de processeur et en démarrera autant que possible en même temps.

time cat count_file.txt | parallel "sleep {}; echo {}"

Connaissez le Dry Run !

Il est maintenant temps d'aborder d'autres exemples concrets de GNU Parallel. Mais, avant de le faire, vous devez d'abord connaître le --dryrun drapeau. Cet indicateur est pratique lorsque vous voulez voir ce qui se passera sans que Parallel le fasse réellement.

Le --dryrun flag peut être la dernière vérification de cohérence avant d'exécuter une commande qui ne se comporte pas comme vous le pensiez. Malheureusement, si vous entrez une commande qui endommagerait votre système, la seule chose que GNU Parallel vous aidera à faire est de l'endommager plus rapidement !

parallel --dryrun "rm rf {}"

Exemple parallèle GNU n° 1 :téléchargement de fichiers depuis le Web

Pour cette tâche, vous allez télécharger une liste de fichiers à partir de diverses URL sur le Web. Par exemple, ces URL peuvent représenter des pages Web que vous souhaitez enregistrer, des images ou même une liste de fichiers provenant d'un serveur FTP.

Pour cet exemple, vous allez télécharger une liste de paquets d'archives (et les fichiers SIG) depuis le serveur FTP de GNU parallèle.

1. Créez un fichier appelé download_items.txt, récupérez quelques liens de téléchargement sur le site de téléchargement officiel et ajoutez-les au fichier séparés par une nouvelle ligne.

 https://ftp.gnu.org/gnu/parallel/parallel-20120122.tar.bz2
 https://ftp.gnu.org/gnu/parallel/parallel-20120122.tar.bz2.sig
 https://ftp.gnu.org/gnu/parallel/parallel-20120222.tar.bz2
 https://ftp.gnu.org/gnu/parallel/parallel-20120222.tar.bz2.sig

Vous pourriez gagner du temps en utilisant la bibliothèque Python's Beautiful Soup pour récupérer tous les liens de la page de téléchargement.

2. Lisez toutes les URL de download_items.txt fichier et transmettez-les à Parallel, qui invoquera wget et transmettez chaque URL.

cat download_items.txt | parallel wget {}

N'oubliez pas que {} dans une commande parallèle est un espace réservé pour la chaîne d'entrée !

3. Peut-être avez-vous besoin de contrôler le nombre de threads que GNU Parallel utilise à la fois. Si oui, ajoutez le --jobs ou -j paramètre à la commande. Le --jobs Le paramètre limite le nombre de threads pouvant s'exécuter simultanément au nombre que vous spécifiez.

Par exemple, pour limiter Parallel au téléchargement de cinq URL à la fois, la commande ressemblerait à ceci :

#!/bin/bash
 cat download_items.txt | parallel --jobs 5 wget {}

Le --jobs Le paramètre dans la commande ci-dessus peut être ajusté pour télécharger n'importe quel nombre de fichiers, tant que l'ordinateur sur lequel vous exécutez a autant de processeurs pour les traiter.

4. Pour démontrer l'effet du --jobs paramètre, ajustez maintenant le nombre de travaux et exécutez le time commande pour mesurer la durée de chaque exécution.

 time cat download_items.txt | parallel --jobs 5 wget {}
 time cat download_items.txt | parallel --jobs 10 wget {}

Exemple GNU Parallel 2 :décompression de packages d'archives

Maintenant que vous avez tous ces fichiers d'archive téléchargés à partir de l'exemple précédent, vous devez maintenant les désarchiver.

Dans le même répertoire que les packages d'archives, exécutez la commande parallèle suivante. Notez l'utilisation du caractère générique (* ). Étant donné que ce répertoire contient à la fois des packages d'archives et les fichiers SIG, vous devez indiquer à Parallel de ne traiter que .tar.bz2 fichiers.

sudo parallel tar -xjf ::: *.tar.bz2

Prime! Si vous utilisez GNU parallèle de manière interactive (pas dans un script), ajoutez le --bar pour que Parallel vous montre une barre de progression pendant l'exécution de la tâche.

Exemple GNU Parallel #3 :suppression de fichiers

Si vous avez suivi les exemples un et deux, vous devriez maintenant avoir de nombreux dossiers dans votre répertoire de travail occupant de l'espace. Alors supprimons tous ces fichiers en parallèle !

Pour supprimer tous les dossiers commençant par parallel- en utilisant Parallel, répertoriez tous les dossiers avec ls -d et dirigez chacun de ces chemins de dossier vers Parallel, en appelant rm -rf sur chaque dossier, comme indiqué ci-dessous.

Souvenez-vous du --dryrun drapeau !

ls -d parallel-*/ | parallel "rm -rf {}"

Conclusion

Vous pouvez désormais automatiser les tâches avec Bash et gagner beaucoup de temps. Ce que vous choisissez de faire avec ce temps dépend de vous. Qu'il s'agisse de gagner du temps, de quitter le travail un peu plus tôt ou de lire un autre article de blog ATA, il est temps de revenir dans votre journée.

Pensez maintenant à tous les scripts de longue durée dans votre environnement. Lesquelles pouvez-vous accélérer avec Parallel ?


Linux
  1. Bash -c avec des paramètres positionnels ?

  2. Linux - Argument de paire parallèle Gnu avec des arguments d'entrée de fichier ?

  3. Paramètres spéciaux de Bash expliqués avec 4 exemples de scripts Shell

  4. Paramètres positionnels de Bash expliqués avec 2 exemples de scripts Shell

  5. Valeur en pourcentage avec GNU Diff

Apprendre Linux avec le Raspberry Pi

Faites-en plus en ligne de commande Linux avec GNU Parallel

Écrire des commentaires dans des scripts bash

Comment créer des boîtes de dialogue GUI dans des scripts Bash avec Whiptail sous Linux

Comment créer des documents avec des scripts Bash

Comment travailler avec l'instruction Case dans les scripts Bash