He pirateado muchos scripts de shell, y a veces las cosas más simples me desconciertan. Hoy me encontré con un script que hizo un uso extenso del :bash (colon) incorporado.
La documentación parece bastante simple:
: (a colon) : [arguments]No haga nada más que expandir argumentos y realizar redireccionamientos. El estado de retorno es cero.
Sin embargo, anteriormente solo he visto esto usado en demostraciones de expansión de shell. El caso de uso en el script que encontré hizo un uso extenso de esta estructura:
if [ -f ${file} ]; then
grep some_string ${file} >> otherfile || :
grep other_string ${file} >> otherfile || :
fi
En realidad, había cientos de greps, pero son más de lo mismo. No hay redireccionamientos de entrada / salida presentes aparte de la estructura simple anterior. No se verifican valores de retorno más adelante en el script.
Estoy leyendo esto como una construcción inútil que dice "o no hacer nada". ¿Para qué sirve terminar estos greps con "o no hacer nada"? ¿En qué caso esta construcción causaría un resultado diferente que simplemente dejar de lado || :todas las instancias?
fuente

:como alternativa atrue. Tal vezerrexitestá configurado y al autor no le importa el estado de salida de algunos comandos.Respuestas:
Parece que los
:s en su secuencia de comandos se están utilizando en lugar detrue. Sigrepno encuentra una coincidencia en el archivo, devolverá un código de salida distinto de cero; Como menciona jw013 en un comentario, sierrexitse establece, probablemente-een la línea shebang, el script se cerraría si alguno de losgreps no logra encontrar una coincidencia. Claramente, eso no es lo que el autor quería, por lo que agregó|| :que el estado de salida de ese comando compuesto en particular siempre es cero, como el más común (en mi experiencia)|| true/|| /bin/true.fuente
truelugar, pero la intención semántica es mucho más claratrue.:es más adecuado cuando se desea un NOP explícito.:lugar detrueporque:es una funciónbashincorporada, comotruesuele ser un binario compilado con más sobrecarga. generalmente lo usotrueporque el código es más legible (del mismo modo, prefiero usarlo ensourcelugar de.).El
:builtin también es útil con la expansión de shell Bash "asignar valores predeterminados", donde la expansión a menudo se usa únicamente para el efecto secundario y el valor expandido se desecha:fuente
Puedo pensar en dos lugares que he usado
:en el pasado.Ese es un ciclo para siempre.
Ponga una función stub, solo para obtener el flujo de control de nivel superior correcto.
Un uso que he visto en los viejos tiempos: en lugar de una línea
#!/bin/sh(o lo que sea), verías una:línea. Algunos de los núcleos más antiguos de Real Unix o shells de Real Unix usarían eso para significar "Soy un script de shell, me han ejecutado". Como recuerdo, esto fue justo cuando csh estaba haciendo incursiones como un shell interactivo común.fuente
:es muy extraño. descubrí que efectivamente hace que se ejecute el scriptsh. donde, como cuando inicia el script sin un shebang ... intenta ejecutar el script con cualquier shell que se esté ejecutando (por lo que si está ejecutandobash, intenta ejecutarlo comobashsi tuviera,cshentonces intenta ejecutarlo comocsh).El
:incorporado ya estaba en el shell de Thompson : está documentado para Unix V6 en 1975. En el shell de Thompson,:indicaba una etiqueta para elgotocomando. Si nunca intentó llamargotoa una línea que comienza:, esa línea fue efectivamente un comentario.El shell Bourne , el antepasado de los shells Bourne / POSIX tal como los conocemos, nunca tuvo uno
gotoque yo sepa, pero se mantuvo:como un comando no operativo (ya estaba presente en Unix V7 ).fuente
Saqué una vieja referencia: "El entorno de programación UNIX" (c) 1984 de Kernighan y Pike.
La página 147 (Programación de Shell) dice esto:
fuente
trueahora también es un shell integrado en muchos sistemas.Me parece recordar que las primeras versiones del shell no tenían una sintaxis de comentarios. Una línea que comience con
:(que probablemente habría sido un ejecutable real, similar a/bin/true) habría sido la mejor alternativa.Aquí hay una página de manual para el antiguo caparazón de Thompson (sin relación); no se menciona ninguna sintaxis de comentarios.
fuente
:hecho fue un indicador de etiqueta para elgotocomando, en algún shell antiguo (no sé cuál). De hecho, una etiqueta: somethingpodría usarse como un comentario, si no hubiera coincidenciagoto. La práctica se mantuvo incluso después degotodesaparecer.":" es útil para la depuración.
Al ejecutarse normalmente, la función de depuración nunca se ejecuta, por lo que sh solo pasa por encima del noop (aunque las variables y los comodines se expanden). Si se requiere una depuración más profunda, elimine el noop de la variable y se llama a la función de depuración con los argumentos necesarios.
Otro uso útil es como un comentario de bloque, que es una característica que falta en la sintaxis de shell.
fuente