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
figletse impriman los argumentos incluso si el figlet no está instalado, ajuste la sugerencia de Olorin de la siguiente manera:fuente
commandviene No lo tengo en mis instalaciones (Red Hat 6.8 Enterprise y Cygwin64).commandes un shell POSIX Bourne incorporado. Normalmente ejecuta el comando proporcionado, pero la-vbandera hace que se comporte más comotypeotro shell integrado.type -a commandte lo mostrará.whichserá únicamente mostrar los ejecutables en sus$PATH, no empotrados, palabras clave, funciones o alias.whichno encuentra un alias aplicable, porque aliaswhichpara ejecutarse/usr/bin/which(!) y el tubo es una lista de alias de la shell que mirar en (Por supuesto\whichsuprime el alias y usa solo el programa, que no muestra alias.)Puedes probar para ver si
figletexistefuente
Una forma común de hacer esto es con
test -xaka[ -x. Aquí hay un ejemplo tomado de/etc/init.d/ntpun sistema Linux:Esta variante se basa en conocer la ruta completa del ejecutable. En
/bin/lesspipeEncontré un ejemplo que funciona alrededor de eso combinando-xy elwhichcomando:De esta forma, esto funcionará sin saber de antemano en qué parte
PATHdelbunzipejecutable se encuentra.fuente
which. E incluso siwhichfunciona, usarlotest -xen su salida es una tontería: si obtiene una rutawhich, existe.test -xhace más que simplemente verificar si existe un archivo (para esotest -eestá). También verifica si el archivo tiene establecidos los permisos de ejecución.which.Al comienzo de su script, verifique si
figletexiste, y si no existe, defina una función de shell que no haga nada:typecomprueba sifigletexiste como un shell incorporado, función, alias o palabra clave,>/dev/null 2>&1descarta stdin y stdout para que no obtenga ningún resultado, y si no existe,figlet() { :; }definefigletcomo 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 quefigletse 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>&1conhash figlet 2>/dev/nullsi 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 elPATHpara 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
~/binque podría o no ser el comando Esperaba.fuente
figletestaba en/usr/local/bino/home/bob/stuff/programs/executable/figlet?El
typecomando 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 encontrarfigleten la ruta (-psignifica solo buscar archivos, no funciones integradas o funciones, y también suprime los mensajes de error), descartando la salida (eso es lo que> /dev/nullhace), y si devuelve verdadero (&&) , se ejecutaráfiglet.Esto es más simple si
figletestá en una ubicación fija:Aquí estamos usando el
testcomando (aka[) para ver si/usr/bin/figletes ejecutable (-x) y si es así (&&) ejecutarlo. Creo que esta solución es más portátil que usartypeque 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 --helpfalla, entonces la instalación está lo suficientemente bloqueada como para que no esté allí.--helpestar disponible. Las utilidades de Posix no lo tienen, por ejemplo, y las pautas de posix realmente recomiendan no hacerlo .at --helpfalla conat: invalid option -- '-', por ejemplo, y un estado de salida de130en mi sistema.-?--help--version... o podría averiguar quéfiglet -0 --illegalexiste y tratarlo como su indicador de éxito (siempre que no sea 127, lo que clasificaría como sabotaje).