¿Por qué escribir un script bash completo en funciones?

En el trabajo, escribo scripts bash con frecuencia. Mi supervisor ha sugerido que todo el script se divida en funciones, similar al siguiente ejemplo:

#!/bin/bash # Configure variables declare_variables() { noun=geese count=three } # Announce something i_am_foo() { echo "I am foo" sleep 0.5 echo "hear me roar!" } # Tell a joke walk_into_bar() { echo "So these ${count} ${noun} walk into a bar..." } # Emulate a pendulum clock for a bit do_baz() { for i in {1..6}; do expr $i % 2 >/dev/null && echo "tick" || echo "tock" sleep 1 done } # Establish run order main() { declare_variables i_am_foo walk_into_bar do_baz } main 

¿Hay alguna razón para hacer esto que no sea «legibilidad» , que creo que podría estar igualmente bien establecido con algunos comentarios más y algo de interlineado?

¿Hace que el script se ejecute de manera más eficiente (en realidad esperaría lo contrario, en todo caso), o hace ¿Es más fácil modificar el código más allá del potencial de legibilidad mencionado anteriormente? ¿O es solo una preferencia de estilo?

Tenga en cuenta que aunque el script no lo demuestra bien, el «orden de ejecución» de las funciones en nuestros scripts reales tiende a ser muy lineal – walk_into_bar depende de las cosas que i_am_foo ha hecho, y do_baz actúa sobre las cosas configuradas por walk_into_bar – por lo que poder cambiar arbitrariamente el orden de ejecución no es algo que normalmente estaríamos haciendo. Por ejemplo, no querría poner de repente declare_variables después de walk_into_bar, eso rompería las cosas.

Un Un ejemplo de cómo escribiría el script anterior sería:

#!/bin/bash # Configure variables noun=geese count=three # Announce something echo "I am foo" sleep 0.5 echo "hear me roar!" # Tell a joke echo "So these ${count} ${noun} walk into a bar..." # Emulate a pendulum clock for a bit for i in {1..6}; do expr $i % 2 >/dev/null && echo "tick" || echo "tock" sleep 1 done 

Comentarios

  • Me gusta tu jefe. En mis scripts también coloco main() en la parte superior y agrego main "$@" en la parte inferior para llamarlo. Eso te permite ver el alto nivel de la lógica de la secuencia de comandos cuando lo abres.
  • No estoy de acuerdo con la idea de que la legibilidad puede » estar igualmente bien establecida con algunos comentarios más y algo de interlineado . » Excepto tal vez por la ficción, yo ‘ t quisiera tratar con un libro que no ‘ t tienen una tabla de contenido y nombres descriptivos para cada capítulo y sección. En los lenguajes de programación, ‘ es el tipo de legibilidad que las funciones pueden proporcionar, un nd comentario ‘ s can ‘ t.
  • Tenga en cuenta que las variables declaradas en funciones deben declararse local: esto proporciona un alcance variable que es increíblemente importante en cualquier script no trivial.
  • No estoy de acuerdo con su jefe. Si tiene que dividir su script en funciones, probablemente no debería ‘ t escribir un script de shell en primer lugar. En su lugar, escriba un programa.
  • Las funciones son para procesos que se repiten, ya sea dentro del script o en más de un script. También permiten implementar metodologías uniformes. Por ejemplo, usar una función para escribir en syslog. Siempre que todos usen la misma función, sus entradas de syslog serán más consistentes. Las funciones de un solo uso, como su ejemplo, complican innecesariamente el script. En algunos casos, introducen problemas (alcance variable).

Respuesta

He empezado a usar este mismo estilo de programación bash después de leer la entrada de blog de Kfir Lavi «Programación defensiva Bash» . Da bastantes buenas razones, pero personalmente considero que estas son las más importantes:

  • los procedimientos se vuelven descriptivos: es mucho más fácil averiguar qué se supone que una parte particular del código que hacer. En lugar de un muro de código, verá «Oh, la función find_log_errors lee ese archivo de registro en busca de errores». Compárelo con encontrar muchas líneas awk / grep / sed que usa Dios sabe qué tipo de expresión regular en medio de un script extenso; no tienes idea de qué está haciendo allí a menos que haya comentarios.

  • Puedes depurar funciones encerrándolo en set -x y set +x. Una vez que sepa que el resto del código funciona bien, puede usar este truco para concentrarse en depurar solo esa función específica. Claro, puede incluir partes del script, pero ¿y si es una parte larga? Es más fácil hacer algo como esto:

     set -x parse_process_list set +x 
  • uso de impresión con cat <<- EOF . . . EOF. Lo he utilizado varias veces para hacer que mi código sea mucho más profesional. Además, parse_args() con la función getopts es bastante conveniente. Nuevamente, esto ayuda con la legibilidad, en lugar de meter todo en el script como una pared gigante de texto. También es conveniente reutilizarlos.

Y obviamente, esto es mucho más legible para alguien que conozca C, Java o Vala, pero que tenga una experiencia limitada en bash. En lo que respecta a la eficiencia, no hay mucho de lo que pueda hacer: bash en sí no es el lenguaje más eficiente y la gente prefiere perl y python cuando se trata de velocidad y eficiencia.Sin embargo, puede nice una función:

nice -10 resource_hungry_function 

En comparación con llamar a nice en todas y cada una de las líneas de código, esto disminuye mucho el tipeo Y se puede usar convenientemente cuando solo desea que una parte de su script se ejecute con menor prioridad.

Ejecutar funciones en segundo plano, en mi opinión, también ayuda cuando desea tener un montón de declaraciones para ejecutar en segundo plano.

Algunos de los ejemplos en los que he usado este estilo:

Comentarios

  • No estoy seguro de que debas tomar muy en serio las sugerencias de ese artículo. De acuerdo, tiene algunas buenas ideas, pero claramente no es alguien acostumbrado a shell scripting. No es un single variable en cualquiera de los ejemplos se cita (!) y sugiere usar MAYÚSCULAS C Nombres de variables ASE, que a menudo son una muy mala idea, ya que pueden entrar en conflicto con las variables env existentes. Tus puntos en esta respuesta tienen sentido, pero el artículo vinculado parece haber sido escrito por alguien que está acostumbrado a otros idiomas y está tratando de forzar su estilo en bash.
  • @terdon Volví al artículo y lo releí. El único lugar donde el autor menciona la denominación de variables en mayúsculas es en » Variables globales inmutables «. Si considera variables globales como aquellas que deben estar dentro del entorno de la función ‘, entonces tiene sentido convertirlas en mayúsculas. En la nota al margen, bash ‘ s manual no ‘ t establece la convención para mayúsculas y minúsculas. Incluso aquí , la respuesta aceptada dice » generalmente » y el único » estándar » es de Google, que no ‘ representa la industria de TI completa.
  • @terdon en otra nota, estoy 100% de acuerdo en que las citas de variables deberían haberse mencionado en el artículo, y también se ha señalado en los comentarios del blog. Además, no ‘ juzgaría a alguien que usa este estilo de codificación, independientemente de si ‘ está o no acostumbrado a otro idioma. Toda esta pregunta y sus respuestas muestran claramente las ‘ ventajas y el grado ‘ en el que ‘ volver a usar otro idioma es probablemente irrelevante aquí.
  • @terdon bueno, el artículo fue publicado como parte de la » fuente » material. Podría haber publicado todo como mis propias opiniones, pero solo tenía que reconocer que algunas de las cosas que aprendí del artículo y que todo esto provino de la investigación a lo largo del tiempo. La página de linkedin del autor ‘ muestra que tiene una buena experiencia con Linux y TI en general, por lo que ‘ supongo que el artículo no id = «9b8d4d3bb1»>

Realmente no demuestro eso, pero confío en su experiencia cuando se trata de Linux y scripts de shell, así que puede que tenga razón.

  • Eso ‘ es una respuesta excelente, pero ‘ también me gustaría agregar que el alcance de la variable en Bash es funky. Por esa razón, prefiero declarar mis variables dentro de funciones usando local y llamando a todo a través de la función main(). Esto hace que las cosas sean mucho más manejables y puede evitar una situación potencialmente complicada.
  • Responder

    La legibilidad es una cosa. Pero hay más en la modularización que solo esto. ( La semimodularización es quizás más correcta para las funciones).

    En las funciones, puede mantener algunas variables locales, lo que aumenta la confiabilidad , disminuyendo la posibilidad de las cosas se estropean.

    Otra ventaja de las funciones es la reutilización . Una vez que se codifica una función, se puede aplicar varias veces en el script. También puede portarlo a otro script.

    Su código ahora puede ser lineal, pero en el futuro puede ingresar al ámbito de multi-threading , o multi-threading procesando en el mundo Bash. Una vez que aprenda a hacer cosas en funciones, estará bien equipado para el paso al paralelo.

    Un punto más para agregar. Como observa Etsitpab Nioliv en el comentario a continuación, es fácil redireccionar las funciones como una entidad coherente. Pero hay un aspecto más de las redirecciones con funciones. Es decir, las redirecciones se pueden establecer a lo largo de la definición de la función. Por ejemplo:

    f () { echo something; } > log 

    Ahora las llamadas a funciones no necesitan redirecciones explícitas.

    $ f 

    Esto puede ahorrar muchas repeticiones, lo que nuevamente aumenta la confiabilidad y ayuda a mantener las cosas en orden.

    Consulte también

    Comentarios

    • Muy bien responder aunque sería mucho mejor si estuviera dividido en funciones.
    • Tal vez agregue que las funciones le permiten importar ese script a otro script (usando source o . scriptname.sh, y use esas funciones como si estuvieran en su nuevo script.
    • Eso ‘ ya está cubierto en otra respuesta.
    • Se lo agradezco. Pero ‘ prefiero dejar que otras personas también sean importantes.
    • Enfrenté un caso hoy donde tuve que redirigir parte de la salida de un script a un archivo (para enviarlo por correo electrónico) en lugar de hacer eco. Simplemente tuve que hacer myFunction > > myFile para redirigir la salida de las funciones deseadas. Bastante conveniente. Podría ser relevante.

    Responder

    En mi comentario, mencioné tres ventajas de las funciones:

    1. Son más fáciles de probar y verificar su exactitud.

    2. Las funciones se pueden reutilizar (obtener) fácilmente en scripts futuros

    3. A tu jefe le gustan.

    Y nunca subestimes la importancia del número 3.

    Me gustaría abordar un tema más:

    … así que poder intercambiar arbitrariamente el orden de ejecución no es algo que normalmente estaríamos haciendo. Por ejemplo, no querría poner de repente declare_variables después de walk_into_bar, eso rompería las cosas.

    Para obtener el beneficio de dividir el código en funciones, se debe intentar que las funciones sean lo más independientes posible. Si walk_into_bar requiere una variable que no se usa en ningún otro lugar, entonces esa variable debe definirse y hacerse local en walk_into_bar. El proceso de separar el código en funciones y minimizar sus interdependencias debe hacer que el código sea más claro y simple .

    Idealmente, las funciones deberían ser fáciles de probar individualmente. Si, debido a las interacciones, no son fáciles de probar, entonces eso es una señal de que podrían beneficiarse de la refactorización.

    Comentarios

    • Yo ‘ d sostengo que ‘ a veces es sensato modelar y hacer cumplir esas dependencias, frente a la refactorización para evitarlas (ya que si hay suficientes h de ellos, y ‘ son lo suficientemente complicados, lo que puede llevar a un caso en el que las cosas ya no están modularizadas en funciones). Un caso de uso muy complicado una vez inspiró un marco para hacer precisamente eso .
    • Lo que debe dividirse en funciones debería ser, pero el ejemplo lo lleva demasiado lejos. Creo que el único que realmente me molesta es la función de declaración de variables. Las variables globales, especialmente las estáticas, deben definirse globalmente en una sección comentada dedicada a ese propósito. Las variables dinámicas deben ser locales para las funciones que las usan y modifican.
    • @Xalorous I ‘ he visto prácticas en las que las variables globales son inicializadas en un procedimiento, como un paso intermedio y rápido antes del desarrollo de un procedimiento que lee su valor de un archivo externo … Estoy de acuerdo en que debería ser más limpio separar la definición y la inicialización, pero rara vez tienes que doblarte para someterte a la ventaja número 3 ;-)

    Responder

    Aunque estoy totalmente de acuerdo con la reutilización , legibilidad y besar delicadamente a los jefes, pero hay otra ventaja de las funciones en : alcance variable . Como muestra LDP :

    #!/bin/bash # ex62.sh: Global and local variables inside a function. func () { local loc_var=23 # Declared as local variable. echo # Uses the "local" builtin. echo "\"loc_var\" in function = $loc_var" global_var=999 # Not declared as local. # Therefore, defaults to global. echo "\"global_var\" in function = $global_var" } func # Now, to see if local variable "loc_var" exists outside the function. echo echo "\"loc_var\" outside function = $loc_var" # $loc_var outside function = # No, $loc_var not visible globally. echo "\"global_var\" outside function = $global_var" # $global_var outside function = 999 # $global_var is visible globally. echo exit 0 # In contrast to C, a Bash variable declared inside a function #+ is local ONLY if declared as such. 

    No veo esto muy a menudo en el mundo real secuencias de comandos de shell, pero parece una buena idea para las secuencias de comandos más complejas. Reducir la cohesión ayuda a evitar errores en los que «estás golpeando una variable esperada en otra parte del código .

    La reutilización a menudo significa crear una biblioteca común de funciones y source incluir esa biblioteca en todos sus scripts. Esto no los ayudará a correr más rápido, pero le ayudará a escribirlos más rápido.

    Comentarios

    • Pocas personas usan explícitamente local, pero creo que la mayoría de las personas que escriben scripts divididos en funciones aún siguen el principio de diseño. Usign local solo dificulta la introducción de errores.
    • local hace que las variables estén disponibles para la función y sus hijos, por lo que ‘ es realmente bueno tener una variable que se pueda pasar por debajo de la función A, pero no disponible para la función B, que puede querer tener una variable con el mismo nombre pero con un propósito diferente.De modo que ‘ es bueno para definir el alcance y, como dijo Voo, menos errores

    Respuesta

    Divide el código en funciones por la misma razón que lo haría para C / C ++, python, perl, ruby o cualquier código de lenguaje de programación. La razón más profunda es la abstracción: encapsula tareas de nivel inferior en primitivas (funciones) de nivel superior para no tener que preocuparse por cómo se hacen las cosas. Al mismo tiempo, el código se vuelve más legible (y mantenible), y el La lógica del programa se vuelve más clara.

    Sin embargo, al mirar su código, me parece bastante extraño tener una función para declarar variables; esto realmente me hace levantar una ceja.

    Comentarios

    • Respuesta infravalorada, en mi humilde opinión. ¿Sugieres declarar las variables en la main función / método, entonces?

    Responder

    Una razón completamente diferente a las ya dadas en otras respuestas: una razón por la que esta técnica se usa a veces, donde la única La declaración de no definición de función en el nivel superior es una llamada a main, es para asegurarse de que el script no haga nada desagradable accidentalmente si se trunca. El script puede estar truncado si esto es canalizado desde el proceso A al proceso B (el shell), y el proceso A termina por cualquier motivo antes de que haya terminado de escribir todo el script. Esto es especialmente probable que suceda si el proceso A recupera el script de un recurso remoto. Si bien por razones de seguridad no es una buena idea, es algo que se hace y algunos scripts se han modificado para anticipar el problema.

    Comentarios

    • ¡Interesante! Pero me preocupa que uno tenga que cuidar esas cosas en cada uno de los programas. Por otro lado, exactamente este main() patrón es habitual en Python, donde se usa if __name__ == '__main__': main() al final del archivo.
    • El lenguaje de Python tiene la ventaja de permitir que otros scripts import el script actual sin ejecutar main. Supongo que se podría poner una protección similar en un script bash.
    • @Jake Cobb Sí. Ahora hago eso en todos los nuevos scripts de bash. Tengo un script que contiene una infraestructura central de funciones utilizadas por todos los nuevos scripts. Ese script se puede obtener o ejecutar. Si se obtiene, su función principal no se ejecuta. La detección de la fuente frente a la ejecución se realiza a través del hecho de que BASH_SOURCE contiene el nombre del script en ejecución. Si ‘ es el mismo que el script principal, el script se está ejecutando. De lo contrario, ‘ se obtiene.
    • Muy relacionado con esta respuesta, bash usa un procesamiento simple basado en líneas cuando se ejecuta desde un archivo que ya está en el disco. Si el archivo cambia mientras se ejecuta el script, el contador de línea no ‘ t cambia y ‘ continuará en la línea incorrecta. Encapsular todo en funciones asegura que ‘ se cargue todo en la memoria antes de ejecutar nada, por lo que alterar el archivo no ‘ no lo afecta.

    Respuesta

    Algunos tópicos relevantes sobre la programación:

    • Su programa cambiará, incluso si su jefe insiste en que este no es el caso.
    • Solo el código y la entrada afectan el comportamiento del programa.
    • Nombrar es difícil.

    Los comentarios comienzan como un remedio para no ser capaz de expresar sus ideas claramente en código * y empeorar (o simplemente equivocarse) con el cambio. Por lo tanto, si es posible, exprese conceptos, estructuras, razonamiento, semántica, flujo, manejo de errores y cualquier otra cosa pertinente a la comprensión del código como código.

    Dicho esto, Las funciones de Bash tienen algunos problemas que no se encuentran en la mayoría de los idiomas:

    • El espacio de nombres es terrible en Bash. Por ejemplo, olvidar usar la palabra clave local da como resultado la contaminación del espacio de nombres global.
    • El uso de local foo="$(bar)" da como resultado perder el código de salida de bar .
    • No hay parámetros con nombre, por lo que debe tener en cuenta lo que "$@" significa en diferentes contextos.

    * Lo siento si esto ofende, pero después utilizando comentarios durante algunos años y desarrollando sin ellos ** durante más años, está bastante claro cuál es superior.

    ** Todavía es necesario utilizar comentarios para licencias, documentación de API y similares.

    Comentarios

    • Establezco casi todas las variables locales declarándolas nulas al comienzo de la función …local foo="" Luego configúrelos usando la ejecución del comando para actuar sobre el resultado … foo="$(bar)" || { echo "bar() failed"; return 1; }. Esto nos saca de la función rápidamente cuando no se puede establecer un valor requerido. Las llaves son necesarias para asegurar que return 1 solo se ejecute en caso de falla.
    • Solo quería comentar sobre sus viñetas. Si usa ‘ funciones de subcapa ‘ (funciones delimitadas por paréntesis y no entre llaves), 1) no ‘ No tienes que usar local pero obtén los beneficios de local, 2) No ‘ no te encuentres con el problema de perder el código de salida de la sustitución de comandos en local foo=$(bar) tanto (porque ‘ no estás usando local) 3) No ‘ no tienes que preocuparte acerca de la contaminación accidental o el cambio del alcance global 4) son capaces de pasar ‘ parámetros con nombre ‘ que son ‘ local ‘ a su función usando la sintaxis foo=bar baz=buz my-command

    Respuesta

    Un proceso requiere una secuencia. La mayoría de las tareas son secuenciales. No tiene sentido meterse con el pedido.

    Pero lo más importante de la programación, que incluye secuencias de comandos, son las pruebas. Pruebas, pruebas, pruebas. ¿Qué secuencias de comandos de prueba tiene actualmente para validar la exactitud de sus secuencias de comandos?

    Su jefe está tratando de guiarlo de ser un niño de guiones a ser un programador. Esta es una buena dirección a seguir. A las personas que vengan después de ti les agradarás.

    PERO. Recuerde siempre sus raíces orientadas al proceso. Si tiene sentido tener las funciones ordenadas en la secuencia en la que normalmente se ejecutan, hágalo, al menos como primer paso.

    Más adelante, verá que algunas de sus funciones son manejando la entrada, otros la salida, otros procesando, otros modelando datos y otros manipulando los datos, por lo que puede ser inteligente agrupar métodos similares, tal vez incluso moverlos en archivos separados.

    Más adelante, puede darse cuenta de que ahora ha escrito bibliotecas de pequeñas funciones auxiliares que utiliza en muchos de sus scripts.

    Respuesta

    Comentarios y el espaciado no puede acercarse a la legibilidad que las funciones pueden, como lo demostraré. Sin funciones, los árboles no pueden ver el bosque; los grandes problemas se esconden entre muchas líneas de detalle. En otras palabras, las personas no pueden concentrarse simultáneamente en los detalles finos y en el panorama general. Eso puede no ser obvio en un guión corto; siempre que sea breve, puede ser lo suficientemente legible. Sin embargo, el software se hace más grande, no más pequeño , y ciertamente es parte de todo el sistema de software de su empresa, que seguramente es mucho más grande, probablemente millones de líneas.

    Considere si le di instrucciones como esta:

    Place your hands on your desk. Tense your arm muscles. Extend your knee and hip joints. Relax your arms. Move your arms backwards. Move your left leg backwards. Move your right leg backwards. (continue for 10,000 more lines) 

    Para cuando llegues a la mitad, o incluso al 5%, habrás olvidado cuáles fueron los primeros pasos. Es posible que no pueda detectar la mayoría de los problemas, porque no puede ver el bosque por los árboles. Compare con funciones:

    stand_up(); walk_to(break_room); pour(coffee); walk_to(office); 

    Eso es ciertamente mucho más comprensible, sin importar cuántos comentarios pueda poner en la versión secuencial línea por línea. también hace que sea mucho más probable que notes que olvidaste hacer el café, y probablemente olvidé sit_down () al final. Cuando su mente está pensando en los detalles de las expresiones regulares grep y awk, no puede «pensar en el panorama general -» ¿y si no se hace café «?

    Las funciones principalmente le permiten ver el panorama general, y observe que olvidó hacer el café (o que alguien podría preferir el té). En otro momento, en un estado de ánimo diferente, se preocupa por la implementación detallada.

    También hay otros beneficios que se analizan en otras respuestas, por supuesto. Otro beneficio que no se indica claramente en las otras respuestas es que las funciones brindan una garantía que es importante para prevenir y corregir errores. Si descubre que alguna variable $ foo en la función adecuada walk_to () estaba mal, sabe que solo tiene que mirar las otras 6 líneas de esa función para encontrar todo lo que pudo haber sido afectado por ese problema, y todo lo que podría han causado que esté mal. Sin las funciones (adecuadas), cualquier cosa en todo el sistema podría ser la causa de que $ foo sea incorrecto, y cualquier cosa y todo podría verse afectado por $ foo. Por lo tanto, no puede reparar de forma segura $ foo sin volver a examinar cada línea del programa. Si $ foo es local para una función, puede garantizar que los cambios sean seguros y correctos marcando solo esa función.

    Comentarios

    • Esta no es ‘ t bash sintaxis.Sin embargo, ‘ es una pena; No ‘ no creo que haya una manera de pasar entradas a funciones como esa. (es decir, pour(); < coffee). Se parece más a c++ o php (creo).
    • @ tjt263 sin los paréntesis, es ‘ s sintaxis de bash: verter café. Con parens, ‘ es prácticamente cualquier otro idioma. 🙂

    Respuesta

    El tiempo es dinero

    Hay otras buenas respuestas que aclaran las razones técnicas para escribir modularmente un script, potencialmente de largo, desarrollado en un entorno de trabajo, desarrollado para ser utilizado por un grupo de personas y no solo para su propio uso.

    Quiero céntrese en una expectativa: en un entorno de trabajo «el tiempo es dinero» . Por lo tanto, la ausencia de errores y el rendimiento de su código se evalúan junto con readibility , capacidad de prueba, mantenibilidad, refactorabilidad, reutilización

    Escribiendo en » módulos « un código reducirá el tiempo de lectura que necesita no solo el codificador , sino incluso el tiempo utilizado por los probadores o por el jefe. Además, tenga en cuenta que el tiempo de un jefe generalmente se paga más que el tiempo de un codificador y que su jefe evaluará la calidad de su trabajo.

    Además, escriba en «módulos» independientes un código (incluso un script bash) le permitirá trabajar en «paralelo» con otro componente de su equipo acortando el tiempo total de producción y utilizando en el mejor de los casos la experiencia del single, para revisar o reescribir una parte sin efectos secundarios en las demás, para reciclar el código que acaba de escribir «tal cual» para otro programa / script, para crear bibliotecas (o bibliotecas de fragmentos), para reducir el tamaño general y la probabilidad de errores relacionados, para depurar y probar a fondo cada parte … y, por supuesto, se organizará en lógica seccione su programa / script y mejore su legibilidad. Todo eso le ahorrará tiempo y dinero. El inconveniente es que debe ceñirse a los estándares y comentar sus funciones (que no tiene nada que no se puede hacer en un entorno de trabajo).

    Cumplir con un estándar ralentizará su trabajo al principio, pero acelerará el trabajo de todos los demás (y el suyo también) después. De hecho, cuando la colaboración crece en número de personas involucradas, esto se convierte en una necesidad ineludible. Entonces, por ejemplo, incluso si creo que las variables globales deben definirse globalmente y no en una función, puedo entender un estándar que las inicializa en una función llamada declare_variables() llamado siempre en la primera línea del main() uno …

    Por último, pero no menos importante, no subestime la posibilidad en el código fuente moderno editores para mostrar u ocultar rutinas selectivamente separadas ( plegado de código ). Esto mantendrá compacto el código y hará que el usuario vuelva a ahorrar tiempo.

    ingrese la descripción de la imagen aquí

    Aquí arriba puedes ver cómo se desdobla solo la función walk_into_bar(). Incluso los otros tenían 1000 líneas de largo cada uno, aún se podía mantener bajo control todo el código en una sola página. Tenga en cuenta que está doblada incluso en la sección donde va a declarar / inicializar las variables.

    Respuesta

    Otra razón que a menudo se pasa por alto es el análisis sintáctico de bash:

    set -eu echo "this shouldn"t run" { echo "this shouldn"t run either" 

    Este script obviamente contiene un error de sintaxis y bash no debería ejecutarlo en absoluto, ¿verdad? Incorrecto.

    ~ $ bash t1.sh this shouldn"t run t1.sh: line 7: syntax error: unexpected end of file 

    Si envolvemos el código en una función, esto «no sucedería:

    set -eu main() { echo "this shouldn"t run" { echo "this shouldn"t run either" } main 
    ~ $ bash t1.sh t1.sh: line 10: syntax error: unexpected end of file 

    Respuesta

    Aparte de las razones dadas en otras respuestas:

    1. Psicología: un programador cuya productividad se mide en líneas de código tendrá un incentivo para escribir código innecesariamente detallado. centrándose en las líneas de código, mayor es el incentivo que tiene el programador para expandir su código con una complejidad innecesaria, lo que no es deseable ya que una mayor complejidad puede llevar a un mayor costo de mantenimiento y un mayor esfuerzo requerido para corregir errores.

    Comentarios

    • No es tan mala respuesta, como dicen los votos negativos. Nota: agc dice, también esto es una posibilidad, y sí, lo es. Él no ‘ no dice que sería la única posibilidad, y no ‘ no acusa a nadie, solo declara los hechos. Aunque creo que hoy en día es casi desconocido una » línea de código » – > » $$ » trabajo por contrato de estilo, en medios indirectos es bastante común, eso sí, la masa del código producido cuenta por los líderes / jefes.

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *