Estoy programando un script de shell de Linux que imprimirá pancartas de estado durante su ejecución solo si la herramienta adecuada, por ejemplo figlet
, está instalada (esto es: accesible en la ruta del sistema ).
Ejemplo:
#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
Me gustaría que mi script funcione sin errores incluso cuando nofiglet
esté instalado .
¿Cuál podría ser un método práctico ?
shell
scripting
executable
Sopalajo de Arrierez
fuente
fuente
figlet ... || true
.figlet || true
, pero en su caso, probablemente, una función de shell que Echos de texto simple Si no se puede imprimir un Banner es más probable que lo que desee.Respuestas:
Mi interpretación usaría una función de contenedor llamada igual que la herramienta; en esa función, ejecute la herramienta real si existe:
Entonces puede haber
figlet arg1 arg2...
cambiado en su secuencia de comandos.A @Olorin se le ocurrió un método más simple: definir una función de contenedor solo si es necesario (si la herramienta no existe):
Si desea que
figlet
se impriman los argumentos incluso si el figlet no está instalado, ajuste la sugerencia de Olorin de la siguiente manera:fuente
command
viene No lo tengo en mis instalaciones (Red Hat 6.8 Enterprise y Cygwin64).command
es un shell POSIX Bourne incorporado. Normalmente ejecuta el comando proporcionado, pero la-v
bandera hace que se comporte más comotype
otro shell integrado.type -a command
te lo mostrará.which
será únicamente mostrar los ejecutables en sus$PATH
, no empotrados, palabras clave, funciones o alias.which
no encuentra un alias aplicable, porque aliaswhich
para ejecutarse/usr/bin/which
(!) y el tubo es una lista de alias de la shell que mirar en (Por supuesto\which
suprime el alias y usa solo el programa, que no muestra alias.)Puedes probar para ver si
figlet
existefuente
Una forma común de hacer esto es con
test -x
aka[ -x
. Aquí hay un ejemplo tomado de/etc/init.d/ntp
un sistema Linux:Esta variante se basa en conocer la ruta completa del ejecutable. En
/bin/lesspipe
Encontré un ejemplo que funciona alrededor de eso combinando-x
y elwhich
comando:De esta forma, esto funcionará sin saber de antemano en qué parte
PATH
delbunzip
ejecutable se encuentra.fuente
which
. E incluso siwhich
funciona, usarlotest -x
en su salida es una tontería: si obtiene una rutawhich
, existe.test -x
hace más que simplemente verificar si existe un archivo (para esotest -e
está). También verifica si el archivo tiene establecidos los permisos de ejecución.which
.Al comienzo de su script, verifique si
figlet
existe, y si no existe, defina una función de shell que no haga nada:type
comprueba sifiglet
existe como un shell incorporado, función, alias o palabra clave,>/dev/null 2>&1
descarta stdin y stdout para que no obtenga ningún resultado, y si no existe,figlet() { :; }
definefiglet
como una función que no hace nada.De esta manera, no tiene que editar cada línea de su script que use
figlet
, o verificar si existe cada vez quefiglet
se llama.Puede agregar un mensaje de diagnóstico, si lo desea:
Como beneficio adicional, dado que no mencionó qué shell está utilizando, creo que esto es compatible con POSIX, por lo que debería funcionar en la mayoría de los shell.
fuente
type figlet >/dev/null 2>&1
conhash figlet 2>/dev/null
si está usando bash. (El OP dijo "si está en mi RUTA".)Otra alternativa: un patrón que he visto en los scripts de configuración automática del proyecto:
En su caso específico, incluso podría hacer,
Si no conoce la ruta específica, puede intentar múltiples
elif
(ver arriba) para probar ubicaciones conocidas, o simplemente usar elPATH
para resolver siempre el comando:En general, cuando escribo guiones, prefiero llamar solo a comandos en ubicaciones específicas especificadas por mí. No me gusta la incertidumbre / riesgo de lo que el usuario final podría haber puesto en ellos
PATH
, quizás en su propio~/bin
.Si, por ejemplo, estaba escribiendo una secuencia de comandos complicada para otros que podrían eliminar archivos en función de la salida de un comando en particular al que estoy llamando, no quisiera recoger accidentalmente algo en su
~/bin
que podría o no ser el comando Esperaba.fuente
figlet
estaba en/usr/local/bin
o/home/bob/stuff/programs/executable/figlet
?El
type
comando bash encuentra un comando, una función, un alias, una palabra clave o una función incorporada (verhelp type
) e imprime la ubicación o definición. También devuelve un código de retorno que representa el resultado de la búsqueda; verdadero (0) si se encuentra. Entonces, lo que estamos haciendo aquí es tratar de encontrarfiglet
en la ruta (-p
significa solo buscar archivos, no funciones integradas o funciones, y también suprime los mensajes de error), descartando la salida (eso es lo que> /dev/null
hace), y si devuelve verdadero (&&
) , se ejecutaráfiglet
.Esto es más simple si
figlet
está en una ubicación fija:Aquí estamos usando el
test
comando (aka[
) para ver si/usr/bin/figlet
es ejecutable (-x
) y si es así (&&
) ejecutarlo. Creo que esta solución es más portátil que usartype
que es un bashismo, creo.Podría hacer una función que haga esto por usted:
(Las citas son necesarias debido a los espacios potenciales)
Entonces simplemente harías:
fuente
o /, diría algo como
fuente
Puede hacer una ejecución de prueba, suprimir cualquier salida y probar el código de éxito / falla. Elija argumentos para figlet para hacer esta prueba de bajo costo. -? o --help o --version son posibilidades obvias.
Se agregó en respuesta al comentario a continuación: si realmente desea probar que existe el figlet, no que sea utilizable, entonces lo haría
fuente
$?
es igual a 127 (en mi sistema Linux). 127 es "comando no encontrado". Pero creo que para los comandos racionales, sicommand --help
falla, entonces la instalación está lo suficientemente bloqueada como para que no esté allí.--help
estar disponible. Las utilidades de Posix no lo tienen, por ejemplo, y las pautas de posix realmente recomiendan no hacerlo .at --help
falla conat: invalid option -- '-'
, por ejemplo, y un estado de salida de130
en mi sistema.-?
--help
--version
... o podría averiguar quéfiglet -0 --illegal
existe y tratarlo como su indicador de éxito (siempre que no sea 127, lo que clasificaría como sabotaje).