Tiempo sus scripts y procedimientos de Bash desde el interior del código

Tiempo sus scripts y procedimientos de Bash desde el interior del código

En general, uno puede usar el tiempo Utilidad bash (ver tiempo de hombre Para obtener más información) para ejecutar un programa y obtener la duración del tiempo de ejecución y los resúmenes de uso de recursos del sistema. Pero, ¿cómo pueden una vez secciones particulares de código, directamente desde el código fuente de Bash?

Usando algunas asignaciones y cálculos de variables fáciles, es posible lograr métricas de tiempo precisas para las ejecuciones de scripts de BASH.

En este tutorial aprenderás:

  • Cómo cronometrar los scripts de Bash utilizando asignaciones y cálculos de variables
  • Cómo usar temporizadores superpuestos para el tiempo secciones específicas de sus scripts
  • Ejemplos que ejemplifican cómo se pueden cronometrar secciones específicas de código
Ejecución de script de sincronización

Requisitos y convenciones de software utilizados

Requisitos de software y convenciones de línea de comandos de Linux
Categoría Requisitos, convenciones o versión de software utilizada
Sistema Independiente de la distribución de Linux
Software Línea de comando bash, sistema basado en Linux
Otro Cualquier utilidad que no esté incluida en el shell bash de forma predeterminada se puede instalar utilizando sudo apt-get instalación de utilidad de utilidad (o yum instalación para sistemas basados ​​en redhat)
Convenciones # - requiere que los comandos de Linux se ejecuten con privilegios raíz directamente como un usuario raíz o mediante el uso de sudo dominio
$-Requiere que los comandos de Linux se ejecuten como un usuario regular no privilegiado

Conceptos básicos de la fecha

Estaremos usando el fecha comando para nuestros horarios. Específicamente, usaremos fecha +%s Para obtener el tiempo en segundos desde la época, o en otras palabras, el número de segundos desde 1970-01-01 00:00:00 UTC.

$ fecha +%s 1607481317 

El comando de fecha también puede proporcionar una precisión de nanosegundos (000000000 ... 999999999), si sus tiempos deben ser súper precisos:

$ fecha +%s%n 1607488248328243029 

Discutir la implementación de los temporizadores precisos de los nanosegundos está fuera del alcance de este artículo, pero háganos saber si este tema le interesa. La configuración sería muy similar a la configuración demostrada a continuación, con algunos cálculos y disposiciones adicionales para manejar los segundos frente a los milisegundos, etc.

Ejemplo 1: Un simple ejemplo de tiempo

Comencemos con un ejemplo fácil, donde cronometamos un solo comando, a saber dormir 1, usando dos fecha +%s comandos y una asignación variable. Almacene el script a continuación en un archivo llamado prueba.mierda:

#!/bin/bash start = "$ (fecha +%s)" dormir 1 duración = $ [$ (fecha +%s) - $ inicio] echo $ duración 
Copiar

Aquí primero indicamos que queremos que el script se ejecute como código bash usando el #!/bin/bash selección de intérpretes. También ejecutamos chmod +x ./prueba.mierda Para hacer que el script se ejecute después de crearlo.

A continuación, establecemos la variable COMENZAR a los segundos actuales desde el momento de la época llamando a una subshell (como lo indica ps) y dentro de esa subshell ejecutamos fecha +%s. Luego usamos el dormir función para pausar nuestro script por un segundo. Tenga en cuenta que el dormir 1 podría ser sustituido por su código de programa real, en otras palabras, la parte que desea tiempo.

Finalmente establecemos una nueva variable DURACIÓN haciendo un cálculo (como lo indica ps) - es decir, que tomamos los segundos actuales desde la época (nuevamente usando fecha +%s desde dentro de una subshell) y luego restando la hora de inicio de la misma. El resultado es el número de segundos que han pasado desde el inicio.

Cuando ejecutamos este script, la salida es como se esperaba:

ps ./prueba.SH 1 

Ejemplo 2: un ejemplo de tiempo un poco más complejo

Esta vez, ampliemos un poco y hagamos los tiempos más modulares. test2.mierda:

#!/bin/bash start1 = "$ (fecha +%s)" dormir 2 end1 = "$ (fecha +%s)" sleep 2 start2 = "$ (fecha +%s)" dormir 3 end2 = "$ (fecha + + %s) "Duración1 = $ [$ end1 - $ start1] duración2 = $ [$ end2 - $ start2] echo" La primera parte del código tomó: $ Duración1 "echo" el "el" el "el" el echo " Se tomó la segunda parte del código: $ Duración2 " 
Copiar

Aquí hicimos una configuración similar al primer ejemplo, pero esta vez cronometramos dos comandos diferentes, usando un doble conjunto de variables, y estructuramos un poco más las cosas usando un FIN variable para ambos comandos. También podríamos haber escrito las últimas líneas de eco de la siguiente manera test3.mierda:

#!/bin/bash start1 = "$ (fecha +%s)" dormir 2 end1 = "$ (fecha +%s)" sleep 2 start2 = "$ (fecha +%s)" dormir 3 end2 = "$ (fecha + + %s) "echo" La primera parte del código tomó: $ [$ end1 - $ start1] "echo" La segunda parte del código tomó: $ [$ end2 - $ start2] " 
Copiar

Como los dos DURACIÓN Las variables fueron de alguna manera innecesarias. El puede haber dejado el código más claro para leer, pero no cumplen otra función real, a diferencia de la COMENZAR y FIN Variables utilizadas para cálculos reales.

Sin embargo, tenga en cuenta que no podríamos haber escrito test4.mierda:

#!/bin/bash start1 = "$ (fecha +%s)" dormir 2 sleep 2 start2 = "$ (fecha +%s)" dormir 3 echo "La primera parte del código tomó: $ [$ (fecha +%s ) - $ start1] "echo" La segunda parte del código tomó: $ [$ (date +%s) - $ start2] " 
Copiar

Debido a que la fecha capturada dentro de la subshell es el momento en que se ejecuta el eco, los tiempos para ambos estarían apagados: los tiempos finales deberían haber estado tomando directamente después de los comandos relevantes.

Tal vez para el segundo momento hubiera sido posible usar un fecha +%s directamente en el eco (como el primer eco solo tomaría algunos milisegundos para ejecutarse, incluso con la subshell y la fecha incluida), pero no es perfecto, y definitivamente no funcionaría si se requiere una sincronización de precisión de nanosegundos. Tampoco es una codificación limpia y más difícil de leer/comprender.

Ejecutemos estos scripts y comparemos la salida:

ps ./Test2.SH La primera parte del código tomó: 2 La segunda parte del código tomó: 3 $ ./Test3.SH La primera parte del código tomó: 2 La segunda parte del código tomó: 3 $ ./Test4.SH La primera parte del código tomó: 7 La segunda parte del código tomó: 3 

El test2.mierda y test3.mierda informó los tiempos correctos, como se esperaba. El test4.mierda Script informó horarios incorrectos, también como se esperaba.

¿Puede ver cuánto tiempo funcionó el script en general, aproximadamente en segundos, independientemente de cualquier momento?? Si su respuesta fue seis segundos, tiene razón. Puedes ver como en test2.mierda y test3.mierda hay un adicional dormir 2 que no se está siendo capturado en los comandos de tiempo. Esto ejemplifica cómo puede cronometrar varias secciones de código.

Ejemplo 3: temporizadores superpuestos

Veamos ahora un ejemplo final que tiene temporizadores superpuestos y tiempos una función.test5.mierda:

#!/bin/bash my_sleep_function () sleep 1 global_start = "$ (date +%s)" function_start = "$ (date +%s)" my_sleep_function function_end = "$ (date +%s)" sleep 2 general_end = " $ (fecha +%s) "echo" la parte de la función del código tomó: $ [$ function_end - $ function_start] segundos para ejecutar "eco" el código general tomó: $ [$ global_end - $  Global_start] segundos para ejecutar " 
Copiar

Aquí definimos una función my_sleep_function que simplemente duerme por un segundo. Luego establecemos un temporizador de inicio general utilizando el General_Start variable y nuevamente nuestro fecha +%s en una subshell. A continuación, iniciamos otro temporizador (el temporizador de funciones basado en el Function_start variable). Ejecutamos la función y terminamos inmediatamente finalizar el temporizador de función configurando el Function_end variable.

Luego hacemos un adicional dormir 2 y luego termine el temporizador general estableciendo el Generar en general Temporizador. Finalmente, generamos la información en un formato agradable cerca del final del script. Los dos eco Las declaraciones no son parte del tiempo, pero su tiempo de ejecución sería mínimo; Por lo general, estamos tratando de cronometrar varias secciones y específicas de nuestro código que tienden a tener duraciones largas como bucles extensos, llamadas de programas externos, muchas subshells, etc.

Veamos el fuera de test5.mierda:

ps ./Test5.SH La parte de la función del código tomó: 1 segundos para ejecutar el código general tomó: 3 segundos para ejecutarse 


Se ve bien. El script cronometró correctamente la función a 1 segundo, y el tiempo de ejecución general de script como 3 segundos, siendo la combinación de la llamada de función y los dos segundos adicionales de sueño.

Tenga en cuenta que si la función es recursivamente, puede tener sentido utilizar una variable de tiempo global adicional a la cual se puede agregar el tiempo de ejecución de la función a. También puede contar el número de llamadas de funciones y luego, al final, dividir el número de llamadas de funciones utilizando antes de Cristo (ref cómo hacer cálculos decimales en Bash usando BC). En este caso de uso, puede ser mejor mover los temporizadores de inicio y detener, así como el cálculo de la duración de la función al interior de la función. Hace un código más limpio y claro y puede eliminar la duplicación de código innecesario.

Conclusión

En este artículo, analizamos el tiempo de varias partes de nuestro código de script de bash usando fecha +%s Como base para obtener segundos desde el momento de la época, así como una o más asignaciones variables para calcular los horarios de rendimiento una o más secciones del código. Usando estos bloques de construcción básicos, uno puede hacer estructuras de medición de tiempo complejas, por función, por llamado script o incluso temporizadores que se superponen (por ejemplo, uno por script, así como una por función, etc.) usando diferentes variables. Disfrutar!

Si está interesado en aprender más sobre Bash, consulte nuestra útil serie de consejos y trucos de línea de comandos de bash.

Tutoriales de Linux relacionados:

  • Cómo construir una aplicación Tkinter utilizando un objeto orientado ..
  • Tutorial de depuración de GDB para principiantes
  • Expresiones regulares de Python con ejemplos
  • Bash Regex avanzado con ejemplos
  • Bucles anidados en guiones Bash
  • Bash Loops con ejemplos
  • Cómo trabajar con la API REST de WooCommerce con Python
  • Instale Arch Linux en VMware Workstation
  • Cómo configurar un servidor OpenVPN en Ubuntu 20.04
  • Bash Avanzado Variable Idióms para la sensibilidad de los casos ..