scripts script resueltos programacion pasar parametros español ejercicios ejemplos comandos shell makefile

shell - programacion - scripts linux ejercicios resueltos



Cómo hacer una interrupción de comando $(shell) que falla (4)

Tengo un Makefile que comienza ejecutando una herramienta antes de aplicar las reglas de compilación (que esta herramienta escribe para mí). Si esta herramienta, que es una secuencia de comandos python, sale con un código de estado no nulo, quiero que GNU Make se detenga allí y no continúe con la construcción del programa.

Actualmente, hago algo como esto (nivel superior, es decir, columna 1):

$(info Generating build rules...) $(shell python collect_sources.py) include BuildRules.mk

Pero esto no se detiene si collect_sources.py sale con un código de estado de 1. Esto también captura la salida estándar de collect_sources.py pero no la imprime, así que tengo la sensación de que estoy mirando en la dirección incorrecta.

Si es posible, la solución debería funcionar incluso cuando un shell simple de MS-DOS es el shell estándar del sistema.

¿Cualquier sugerencia?


Asegúrese de no invocar make / gmake con la opción -k.


Bien, aquí está mi propia solución, que desafortunadamente no se basa en el código de estado de la secuencia de comandos collect_sources.py, pero que funciona para mí (TM) y me permite ver cualquier resultado que produzca la secuencia de comandos:

SHELL_OUTPUT := $(shell python collect_sources.py 2>&1) ifeq ($(filter error: [Errno %],$(SHELL_OUTPUT)),) $(info $(SHELL_OUTPUT)) else $(error $(SHELL_OUTPUT)) endif

El script se escribe para que cualquier error produzca un resultado que comience con "collect_sources: error:" . Además, si python no puede encontrar o ejecutar el script dado, "[Errno 2]" un mensaje de error que contiene el mensaje "[Errno 2]" o similar. Así que este pequeño fragmento de código simplemente captura la salida (redireccionando stderr a stdout) y busca mensajes de error. Si no se encuentra ninguno, simplemente usa $(info) para imprimir el resultado, de lo contrario, usa $(error) , lo que hace que Make se detenga.

Tenga en cuenta que la sangría en el ifeq ... endif se hace con espacios. Si se utilizan pestañas, Make cree que está intentando invocar un comando y se queja de ello.


Deberías usar un objetivo regular para crear BuildRules.mk:

BuildRules.mk: collect_sources.py python $< >$@ include BuildRules.mk

Este es el truco estándar para usar cuando se generan dependencias automáticamente.


Puede haber una manera mejor, pero intenté lo siguiente y funciona:

$(if $(shell if your_command; then echo ok; fi), , $(error your_command failed))

Aquí your_command que your_command no da ningún resultado, pero no debería ser difícil trabajar en una situación como esa.

Editar: para que funcione con el shell predeterminado de Windows (y probablemente cualquier shell decente), puede escribir your_command && echo ok lugar del if dentro de la función de shell . No creo que esto sea posible para shells (antiguos) de DOS. Para estos, probablemente quiera adaptar su your_command o escribir un script de envoltura para imprimir algo por error (o éxito).