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 vezerrexit
está 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
. Sigrep
no encuentra una coincidencia en el archivo, devolverá un código de salida distinto de cero; Como menciona jw013 en un comentario, sierrexit
se establece, probablemente-e
en la línea shebang, el script se cerraría si alguno de losgrep
s 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
true
lugar, pero la intención semántica es mucho más claratrue
.:
es más adecuado cuando se desea un NOP explícito.:
lugar detrue
porque:
es una funciónbash
incorporada, comotrue
suele ser un binario compilado con más sobrecarga. generalmente lo usotrue
porque el código es más legible (del mismo modo, prefiero usarlo ensource
lugar 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 comobash
si tuviera,csh
entonces 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 elgoto
comando. Si nunca intentó llamargoto
a 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
goto
que 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
true
ahora 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 elgoto
comando, en algún shell antiguo (no sé cuál). De hecho, una etiqueta: something
podría usarse como un comentario, si no hubiera coincidenciagoto
. La práctica se mantuvo incluso después degoto
desaparecer.":" 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