He notado muchas preguntas, respuestas y comentarios que expresan desdén por (y a veces incluso miedo) de escribir guiones en lugar de frases ingeniosas. Entonces, me gustaría saber:
¿Cuándo y por qué debería escribir un guión independiente en lugar de un "one-liner"? ¿O viceversa?
¿Cuáles son los casos de uso y las ventajas y desventajas de ambos?
¿Algunos idiomas (p. Ej., Awk o perl) son más adecuados para las frases simples que otros (p. Ej., Python)? Si es así, ¿por qué?
¿Es solo una cuestión de preferencia personal o hay buenas razones (es decir, objetivas) para escribir una u otra en circunstancias particulares? ¿Cuáles son esas razones?
Definiciones
one-liner
: cualquier secuencia de comandos escritos o pegados directamente en una línea de comandos de shell . Tuberías menudo implican y / o el uso de lenguajes tales comosed
,awk
,perl
, y / o herramientas comogrep
ocut
osort
.Es la ejecución directa en la línea de comandos la característica definitoria: la longitud y el formato son irrelevantes. Un "one-liner" puede estar todo en una línea, o puede tener múltiples líneas (p. Ej. Sh for loop, o código awk o sed incrustado, con avances de línea e indentación para mejorar la legibilidad).
script
: cualquier secuencia de comandos en cualquier idioma interpretado que se guarde en un archivo y luego se ejecute. Un script puede estar escrito completamente en un idioma, o puede ser un contenedor de script de shell alrededor de varios "one-liners" usando otros idiomas.
Tengo mi propia respuesta (que publicaré más adelante), pero quiero que esto se convierta en un Q&A canónico sobre el tema, no solo mi opinión personal.
Respuestas:
Otra respuesta basada en la experiencia práctica.
Usaría una línea si fuera un código de "descarte" que podría escribir directamente en el indicador. Por ejemplo, podría usar esto:
Usaría un script si decidiera que vale la pena guardar el código. En este punto, agregaría una descripción en la parte superior del archivo, probablemente agregaría alguna comprobación de errores, y tal vez incluso lo verificaría en un repositorio de código para el control de versiones. Por ejemplo, si decidiera que verificar el tiempo de actividad de un conjunto de servidores era una función útil que usaría una y otra vez, la línea anterior podría expandirse a esto:
Generalizando, se podría decir
Un trazador de líneas
Guión
cron
)Veo un buen número de preguntas aquí en Unix. SE pide una línea para realizar una tarea en particular. Usando mis ejemplos anteriores, creo que el segundo es mucho más comprensible que el primero y, por lo tanto, los lectores pueden aprender más de él. Una solución se puede derivar fácilmente de la otra, por lo que, en aras de la legibilidad (para futuros lectores), probablemente deberíamos evitar proporcionar código comprimido en una línea para cualquier otra cosa que no sea la solución más trivial.
fuente
set -- host1 host2 host3
entoncesfor h in "$@"
(o simplementefor h
), lo que haría que la secuencia de comandos sea POSIX portátil. :-)Escribe un guión cuando:
Escribe una frase cuando:
fuente
Cuando una serie requerida de comandos es bastante corta y / o produce un resultado que podría utilizarse como parte de una tubería más grande o un alias de comando, podría ser una buena línea.
Básicamente, creo que las frases simples suelen ser cosas que un administrador experimentado del sistema, familiarizado tanto con el problema como con los comandos utilizados, podría escribir en el acto, sin pensar demasiado.
Cuando una línea se vuelve excesivamente larga o involucra más que condicionales o bucles muy simples, generalmente es mejor escribirlos como un script de varias líneas o una función de shell, para facilitar la lectura. Además, si es algo que usted escribe para ser utilizado una y otra vez, o algo que será utilizado (y posiblemente solucionado) por otras personas, debe estar dispuesto a pasar el tiempo para escribir la solución en un claro (er), comentó: forma de guión
En Python, la sangría es parte de la sintaxis, por lo que literalmente no puede usar las características del lenguaje en toda su extensión si escribe una línea.
Perl y awk one-liners a menudo tratan de usar el poder bruto de las expresiones regulares. Pero algunos llaman a las expresiones regulares Lenguaje de solo escritura, no del todo sin razón. Escribir un guión de varias líneas le permite escribir comentarios para describir lo que se supone que está haciendo una expresión regular en particular, lo que será muy útil cuando vuelva a mirar el guión, después de hacer otras cosas durante seis meses.
Esta es una pregunta inherentemente muy basada en la opinión, ya que implica medir qué cantidad de complejidad es aceptable y compensaciones entre legibilidad y compacidad; Todos estos son asuntos de juicio personal. Incluso la elección de un idioma puede depender de asuntos personales: si un idioma en particular sería teóricamente óptimo para un problema en particular, pero no está familiarizado con él y ya sabe cómo resolver el problema con otro idioma, puede elegir el lenguaje familiar para hacer el trabajo rápidamente y con el mínimo esfuerzo, aunque la solución podría ser técnicamente algo ineficiente.
Lo mejor es a menudo enemigo de lo suficientemente bueno , y esto se aplica mucho aquí.
Y si está familiarizado con Perl, es posible que ya haya oído hablar de TMTOWTDI: hay más de una forma de hacerlo.
fuente
Tenga en cuenta que esta es una opinión personal; Tómelo con un grano de sal.
Si el comando se ajusta dentro de, digamos, 80 caracteres, use una línea. Las líneas de comando largas son difíciles de trabajar. También está el problema de la recurrencia, ver # 2
Si necesita ejecutar los comandos más de una vez, use un script. De lo contrario, use una línea, siempre que se cumpla la condición n. ° 1.
fuente
Veo y utilizo un one-liner como herramienta de desarrollo temporal para editar repetidamente hasta que haga lo que quiero, o entiendo cómo funciona la sutileza de un subcomando.
Luego se anota (y se anota) en un archivo de texto sobre el tema que estaba investigando, o se limpia en un script que se coloca en mi bin PATH personal, posiblemente para un mayor refinamiento, parametrización, etc. Por lo general, la línea única se dividirá en más legible, incluso si no se realizan otros cambios, o si nunca uso el script nuevamente.
Configuré mi historial de shell en más de 5000 líneas, con un historial separado por terminal, y por inicio de sesión en un control remoto, etc. Odio no poder encontrar en estas historias un comando de una línea que desarrollé hace unas semanas y no pensé que lo volvería a necesitar, de ahí mi estrategia.
A veces, un grupo completo de comandos necesita hacer algo, como configurar algún hardware; al final, los copio de la historia, los limpio mínimamente y los agrego a un script de shell
RUNME
como notas sobre lo que hice, pero también para que estén casi listos para ser utilizados nuevamente por otra persona. (Esta es la razón por la que encuentro herramientas que solo proporcionan una GUI para configurarlos.) Me parece una ganancia increíble en eficiencia, ya que a menudo algo que esperas hacer solo una vez, debe hacerse otras 5 veces. .fuente
ln
vs.ln -s
por enlaces duros vs. blandos en una línea que recorre algunos archivos.Me gustaría que las personas de mi equipo escriban scripts para cualquier operación que se requiera que se realice más de una vez (es decir, "flujos de trabajo" o "canalizaciones"), y para cualquier tarea única que deba documentarse (normalmente cosas como "modificar ciertas cosas en algunos conjuntos de datos para corregir datos suministrados incorrectamente" en nuestro caso). Aparte de eso, "one-liners" o scripts no importan demasiado.
No documentar adecuadamente los flujos de trabajo (como scripts o equivalentes) dificulta la introducción de nuevo personal en un proyecto, y también dificulta la transición de las personas fuera de un proyecto. Además, dificulta cualquier tipo de auditoría, y rastrear errores puede ser imposible.
Esto es independientemente del lenguaje utilizado para la programación.
Otros lugares de trabajo pueden tener costumbres o expectativas similares / diferentes, tal vez incluso escritas.
En casa, haces lo que te apetece.
Por ejemplo, escribo scripts tan pronto como hago algo no trivial en el shell, como antes de enviar una respuesta a una pregunta U&L, o cada vez que necesito probar los componentes individuales de un comando o un conjunto de comandos antes de ejecutarlo "para real".
También escribo guiones para tareas repetitivas que realmente quiero hacer de la misma manera cada vez, incluso si son simples, como
Utilizo funciones de shell (rara vez alias) por conveniencia en shells interactivos, por ejemplo, para agregar opciones a ciertos comandos de forma predeterminada (
-F
parals
) o para crear variaciones especializadas de algunos comandos (pman
aquí hay unman
comando que solo mira los manuales POSIX, por ejemplo) .fuente
Parece que tengo una opinión minoritaria sobre esto.
El término "guión" es intencionalmente confuso, deshazte de él. Este es un software que está escribiendo allí, incluso si está utilizando únicamente
bash
yawk
.Dentro de un equipo, prefiero escribir software con un proceso de revisión de código impuesto por una herramienta (github / gitlab / gerrit). Esto le da control de la versión como un bono. Si tiene varios sistemas, agregue herramientas de implementación continua. Y algunas suites de prueba, si los sistemas de destino son importantes. No soy religioso acerca de estos, pero sopesar los beneficios y costos.
Si tiene un equipo de administradores, lo más simple
vim /root/bin/x.sh
es principalmente un desastre en términos de comunicación relacionada con el cambio, legibilidad del código y distribución entre sistemas. A menudo, un mal funcionamiento grave cuesta más tiempo / dinero que el proceso supuestamente "pesado".Yo prefiero una sola línea en realidad para cualquier cosa que no merece ese proceso "pesado". Se pueden reutilizar rápidamente, con unas pocas pulsaciones de teclas, si sabe cómo utilizar su historial de shell de manera efectiva; pegado fácilmente entre sistemas no relacionados (por ejemplo, diferentes clientes).
Diferencia crucial entre (¡no revisado!) One-liners y el software revisado ("scripts"): la responsabilidad recae completamente en usted cuando ejecuta one-liners. Nunca puede decirse a sí mismo: "Acabo de encontrar esta frase en alguna parte, la ejecuté sin entender, lo que siguió no es mi culpa". Sabía que está ejecutando un software no revisado y no probado, por lo que es su culpa. Asegúrate de que sea lo suficientemente pequeño como para poder prever los resultados; maldita sea si no lo haces.
Algunas veces necesita este enfoque simplista, y establecer la barra en aproximadamente una línea de texto funciona bien en la práctica (es decir, el límite entre el código revisado y el no revisado). Algunos de mis discursos parecen terriblemente largos, pero funcionan de manera efectiva para mí. Mientras los asimile y no lo apunte a más colegas jóvenes, todo está bien. En el momento en que necesito compartirlos, paso por el proceso estándar de desarrollo de software.
fuente
Debo decir que estoy algo horrorizado por las implicaciones de las primeras partes de la pregunta. Los lenguajes de secuencias de comandos de Unix son lenguajes de programación completos, y los lenguajes de programación son lenguajes , lo que significa que son tan infinitamente maleables y flexibles como los lenguajes humanos. Y una de las características distintivas de la "maleabilidad y flexibilidad infinitas" es que casi nunca hay "una forma correcta" de expresar algo: hay muchas formas, ¡y esto es algo bueno! Entonces, sí, por supuesto , es una cuestión de preferencia personal, y no hay nada de malo en eso. Cualquiera que diga que solo hay una forma de hacer algo,
Érase una vez, la mía
~/bin
estaba llena de pequeños guiones "útiles" que había escrito. Pero me di cuenta de que la mayoría de ellos se acostumbraron el día que los escribí, y nunca más. Entonces, cuanto más tiempo pasa, más pequeño sebin
vuelve mi directorio.No creo que haya nada malo en escribir un guión. Si imagina que usted u otra persona podrían usarlo nuevamente, por supuesto, escriba un guión. Si desea "diseñar adecuadamente" un script compatible por el bien, hágalo por todos los medios. (Incluso si nadie lo usa, escribirlo es una buena práctica).
Motivos por los que ya no escribo scripts (y, supongo, prefiero "one-liners"):
bin
el desorden del directorio tiene un costo. No pongo más cosas allí a menos que realmente pertenezcan allí.fuente
Creo que la mayoría de las veces la solicitud de un "one-liner" es, de hecho, una solicitud de un "bocado", es decir:
La gente quiere y solicita el código más corto que demuestre una solución a la pregunta formulada.
A veces, no hay forma de reducir un discurso a un "sonido", así como puede ser imposible reducir un guión a un breve "trazo". En tales casos, la única respuesta posible es un script.
Y, en general, un "sonido" nunca es un buen sustituto de todo el discurso. Por lo tanto, un "one liner" generalmente solo es bueno para transmitir una idea o para dar un ejemplo práctico de esa idea. Luego, una vez que se entiende la idea, debe expandirse (aplicarse) en un script.
Por lo tanto, escriba un "one-liner" para transmitir una idea o concepto.
Escriba su código general como scripts completos, no de una sola línea.
fuente
Preguntas sobre "miedo y desdén de los guiones". Esto se debe a la situación de Q + A, donde a menudo la respuesta dice: necesita este paso y este, pero también puedo ponerlo en una línea (para que pueda copiarlo y pegarlo y usarlo como un comando largo y simple).
A veces solo puede adivinar si la Q está mejor servida con una solución de copia y pegado rápida y sucia, o si un script "agradable" es exactamente lo que la Q necesita entender.
Muchos de los pros y los contras aquí son ciertos, pero aún así están perdiendo el punto. Incluso diría que las definiciones en la Q no son útiles.
Los archivos de historial de shell son "one liners", pero aún así se guardan. La función bash
operate-and-get-next (C-o)
incluso te permite repetirlos semiautomáticamente.Apenas veo la palabra función mencionada. Esa es la forma de almacenar "scripts" y "one liners". Y con unas pocas teclas puede cambiar entre ambos formatos. Un comando compuesto a menudo puede adaptarse a ambos.
history -r file
es la forma de leer una o varias líneas de comando (y comentarios) de cualquier archivo, no solo del archivo de historial predeterminado. Solo se necesita una organización mínima. No debe confiar en un gran tamaño de archivo de historial y búsqueda de historial para recuperar (alguna) versión de una línea de comando.Las funciones deben definirse de manera similar. Para empezar, coloque
thisfunc() {...}
un archivo "funciones" en su directorio de inicio y búsquelo. Sí, esto es una sobrecarga, pero es la solución general.Si almacena cada línea de comando y cada variación del script en un archivo separado, es un desperdicio (teórico, pero objetivo) de bloques del sistema de archivos.
Un trazador de líneas no tiene nada rápido y sucio por sí mismo. Es más la parte de copiar y pegar que está mal vista, y cómo solo confiamos en el historial de comandos para guardarlo para nosotros.
@sitaram: su única línea realmente tiene características poco exclusivas : línea shebang, nueva línea, cuatro llamadas de servicios públicos, dos de ellas son "programas". Creo que el script perl original se veía mejor y se ejecutó más rápido y no desperdició ningún byte extendiéndose en 60 líneas. Y perl también te permite apretar un poco.
Para mí, ese es exactamente el tipo de revestimiento que se debe evitar. ¿Le gustaría tener eso (pegado) en su línea de comando? No, y luego, si lo almacena en un archivo de todos modos (no importa el script o la función), podría invertir dos o tres bytes de nueva línea para que se vea --- agradable.
10 minutos. más tarde: solo quería comprobar si puedo decir "dos programas sed" o si son "dos sustituciones / llamadas sed". Pero la respuesta de sitaram se ha ido. Mi respuesta todavía tiene sentido, espero.
fuente