Temps vos scripts et procédures de bash de l'intérieur du code

Temps vos scripts et procédures de bash de l'intérieur du code

En général, on peut utiliser le temps Utilitaire de bash (voir temps de l'homme pour plus d'informations) pour exécuter un programme et obtenir des résumés de durée d'exécution et d'utilisation des ressources système. Mais comment peut-il une fois des sections de code particulières, directement à partir du code source bash?

En utilisant des affectations et des calculs variables faciles, il est possible d'obtenir des mesures de synchronisation précises pour les exécutions de script bash.

Dans ce tutoriel, vous apprendrez:

  • Comment détenir des scripts à l'aide de tasses et de calculs variables
  • Comment utiliser les minuteries qui se chevauchent pour chronométrer les sections spécifiques de vos scripts
  • Exemples qui illustrent comment des sections de code spécifiques peuvent être chronométrées
Exécution du script de bash

Exigences et conventions logicielles utilisées

Exigences logicielles et conventions de ligne de commande Linux
Catégorie Exigences, conventions ou version logicielle utilisée
Système Indépendant de la distribution Linux
Logiciel Ligne de commande bash, système basé sur Linux
Autre Toute utilité qui n'est pas incluse dans le shell bash par défaut peut être installée en utilisant Sudo Apt-Get Install Utility-Name (ou Installation de miam pour les systèmes basés sur Redhat)
Conventions # - nécessite que les commandes Linux soient exécutées avec des privilèges racine soit directement en tant qu'utilisateur racine, soit par l'utilisation de Sudo commande
$ - exige que les commandes Linux soient exécutées en tant qu'utilisateur régulier non privilégié

Date de base

Nous utiliserons le date commande pour nos horaires. Plus précisément, nous utiliserons Date +% S Pour obtenir l'heure en quelques secondes depuis l'époque, ou en d'autres termes, le nombre de secondes depuis 1970-01-01 00:00:00 UTC.

$ Date +% S 1607481317 

La commande de date peut également fournir des nanosecondes (000000000… 999999999), si vos horaires doivent être super précis:

$ Date +% S% N 1607488248328243029 

Discuter de la mise en œuvre de Nanoseconde Precise Tirserrs est en dehors de la portée de cet article, mais veuillez nous faire savoir si ce sujet vous intéresse. La configuration serait très similaire à la configuration démontrée ci-dessous, avec quelques calculs et dispositions supplémentaires pour gérer les secondes par rapport aux millisecondes, etc.

Exemple 1: Un exemple de timing simple

Commençons par un exemple facile, où nous chronométer une seule commande, à savoir sommeil 1, en utilisant deux Date +% S commandes et une affectation variable. Stockez le script ci-dessous dans un fichier appelé test.shot:

#!/ bin / bash start = "$ (date +% s)" Sleep 1 durée = $ [$ (date +% s) - $ start] echo $ durée 
Copie

Ici, nous indiquons d'abord que nous voulons que le script soit exécuté sous forme de code bash en utilisant le #!/ bac / bash Sélection des interprètes. Nous avons également exécuté chmod + x ./test.shot Pour rendre le script exécutable après l'avoir créé.

Ensuite, nous définissons la variable COMMENCER aux secondes actuelles depuis le temps de l'époque en appelant une sous-coquille (comme indiqué par $ (…)) et dans ce sous-coquille, nous exécutons Date +% S. Nous utilisons ensuite le dormir fonction pour suspendre notre script pendant une seconde. Notez que le sommeil 1 pourrait être substitué à votre code de programme réel, en d'autres termes, la partie que vous souhaitez chronométrer.

Enfin, nous définissons une nouvelle variable DURÉE en faisant un calcul (comme indiqué par $ […]) - à savoir que nous prenons les secondes en cours depuis l'époque (encore en utilisant Date +% S à l'intérieur d'une sous-coquille) puis soustraire l'heure de début à la même. Le résultat est le nombre de secondes qui se sont écoulées depuis le début.

Lorsque nous exécutons ce script, la sortie est comme prévu:

$ ./test.sh 1 

Exemple 2: Exemple de synchronisation un peu plus complexe

Cette fois, étendons un peu et rendons les horaires plus modulaires. test2.shot:

#!/ bin / bash start1 = "$ (date +% s)" sleep 2 end1 = "$ (date +% s)" sleep 2 start2 = "$ (date +% s)" sleep 3 end2 = "$ (date + % s) "Durée1 = $ [$ end1 - $ start1] durée2 = $ [$ end2 - $ start2] echo" La 1ère partie du code a pris: $ durée1 "echo" La La 2ème partie du code a pris: $ durée2 " 
Copie

Ici, nous avons fait une configuration similaire au premier exemple, mais cette fois, nous avons chronométré deux commandes différentes, en utilisant un double ensemble de variables, et nous avons structuré les choses un peu plus en utilisant un FIN variable pour les deux commandes. Nous aurions également pu écrire les dernières lignes d'écho comme suit test3.shot:

#!/ bin / bash start1 = "$ (date +% s)" sleep 2 end1 = "$ (date +% s)" sleep 2 start2 = "$ (date +% s)" sleep 3 end2 = "$ (date + % s) "echo" La 1ère partie du code a pris: $ [$ end1 - $ start1] "echo" La 2ème partie du code a pris: $ [$ end2 - $ start2] " 
Copie

Comme les deux DURÉE Les variables étaient à certains égards inutiles. Le peut avoir rendu le code plus clair à lire, mais ils remplissent aucune autre fonction réelle, contrairement au COMMENCER et FIN Variables utilisées pour les calculs réels.

Notez cependant que nous n'aurions pas pu écrire test4.shot:

#!/ bin / bash start1 = "$ (date +% s)" sleep 2 sleep 2 start2 = "$ (date +% s)" sleep 3 echo "La 1ère partie du code a pris: $ [$ (date +% s ) - $ start1] "echo" La 2ème partie du code a pris: $ [$ (date +% s) - $ start2] " 
Copie

Parce que la date capturée à l'intérieur de la sous-coquille est le moment où l'écho est exécuté, les horaires des deux seraient désactivés: les horaires finaux auraient dû prendre directement après les commandes pertinentes.

Peut-être que pour le deuxième timing, il aurait été possible d'utiliser un Date +% S directement dans l'Echo (car le premier écho ne prendrait que quelques millisecondes à exécuter, même avec la sous-coque et la date incluses), mais ce n'est pas parfait, et ne fonctionnerait certainement pas si le timing de précision de la nanoseconde est requis. Ce n'est pas non plus un codage propre et plus difficile à lire / comprendre.

Exécutons ces scripts et comparons la sortie:

$ ./ test2.sh La 1ère partie du code a pris: 2 La 2ème partie du code a pris: 3 $ ./ test3.sh La 1ère partie du code a pris: 2 La 2ème partie du code a pris: 3 $ ./ test4.sh La 1ère partie du code a pris: 7 La 2ème partie du code a pris: 3 

Le test2.shot et test3.shot des horaires corrects signalés, comme prévu. Le test4.shot Le script a signalé des horaires incorrects, également comme prévu.

Pouvez-vous voir combien de temps le script a fonctionné dans l'ensemble, en plus en quelques secondes, quels que soient les horaires? Si vous répondez était six secondes, vous avez raison. Vous pouvez voir comment test2.shot et test3.shot il y a un supplément sommeil 2 qui n'est pas capturé dans les commandes de synchronisation. Cela illustre comment vous pouvez chronométrer diverses sections de code.

Exemple 3: minuteries qui se chevauchent

Regardons maintenant un dernier exemple qui a des minuteries qui se chevauchent et fois une fonction.test5.shot:

#!/ bin / bash my_sleep_function () sleep 1 global_start = "$ (date +% s)" function_start = "$ (date +% s)" my_sleep_function function_end = "$ (date +% s)" sleep 2 global_end = " $ (date +% s) "echo" La partie de fonction du code a pris: $ [$ function_end - $ function_start] secondes pour exécuter "echo" le code global a pris: $ [$ global_end - $  Global_start] secondes pour courir " 
Copie

Ici, nous définissons une fonction my_sleep_function qui dort simplement une seconde. Nous avons ensuite défini une minuterie de démarrage globale en utilisant le Global_start variable et encore notre Date +% S dans une sous-coque. Ensuite, nous commençons une autre minuterie (la minuterie de fonction basée sur le Function_start variable). Nous exécutons la fonction et terminons terminer immédiatement le temporisateur de fonction en définissant le Function_end variable.

Nous faisons ensuite un supplément sommeil 2 puis terminer la minuterie globale en définissant le Global_end minuteur. Enfin, nous étions les informations dans un bon format vers la fin du script. Les deux écho Les déclarations ne font pas partie du calendrier, mais leur temps d'exécution serait minime; Habituellement, nous tentons de chronométrer diverses sections de notre code qui ont tendance à avoir de longues durées comme des boucles étendues, des appels de programme externes, de nombreuses sous-coquilles, etc.

Regardons la sortie de test5.shot:

$ ./ test5.sh La partie de la fonction du code a pris: 1 seconde pour exécuter le code global a pris: 3 secondes pour exécuter 


Cela semble bon. Le script a correctement chronométré la fonction à 1 seconde, et l'exécution globale du script en 3 secondes, étant la combinaison de l'appel de la fonction et le sommeil supplémentaire de deux secondes.

Notez que si la fonction est récursivement, il peut être logique d'utiliser une variable de synchronisation globale supplémentaire à laquelle l'exécution de la fonction peut être ajoutée à. Vous pouvez également compter le nombre d'appels de fonctions, puis à la fin divisez le nombre d'appels de fonction en utilisant avant JC (ref comment faire des calculs décimaux en bash en utilisant la Colombie-Britannique). Dans ce cas d'utilisation, il peut être préférable de déplacer les minuteries de départ et d'arrêt, ainsi que le calcul de la durée de la fonction à l'intérieur de la fonction. Il rend un code plus propre et plus clair et peut éliminer la duplication de code inutile.

Conclusion

Dans cet article, nous avons examiné la chronométrage de différentes parties de notre code de script bash en utilisant Date +% S comme base pour obtenir des secondes depuis le temps de l'époque, ainsi qu'une ou plusieurs affectations variables pour calculer les horaires des performances une ou plusieurs sections du code. En utilisant ces blocs de construction de base, on peut faire des structures de mesure de synchronisation complexes, par fonction, par script appelé ou même des minuteries qui se chevauchent (par exemple un par script ainsi qu'un par fonction, etc.) en utilisant différentes variables. Apprécier!

Si vous êtes intéressé à en savoir plus sur Bash, veuillez consulter nos séries de conseils de commande de commande et de trucs utiles.

Tutoriels Linux connexes:

  • Comment créer une application Tkinter à l'aide d'un objet orienté…
  • Tutoriel de débogage GDB pour les débutants
  • Python Expressions régulières avec des exemples
  • Advanced Bash Regex avec des exemples
  • Boucles imbriquées dans les scripts bash
  • Boucles de bash avec des exemples
  • Comment travailler avec l'API WooCommerce REST avec Python
  • Installez Arch Linux dans VMware Workstation
  • Comment configurer un serveur OpenVPN sur Ubuntu 20.04
  • Bash Idioms variables avancées pour la sensibilité à la caisse…