2009-04-14 14 views
17

Utilizo un Makefile (con GNU make corriendo bajo Linux) para automatizar mi trabajo de grunt al refacturar un script de Python. La secuencia de comandos crea un archivo de salida y quiero asegurarme de que el archivo de salida permanezca sin cambios frente a mis refactorizaciones.Códigos de estado del shell en make

Sin embargo, no encontré ninguna forma de obtener el código de estado de un comando para afectar un shell posterior si el comando.

La regla siguiente ilustra el problema:

check-cond-codes: 
    diff report2008_4.csv report2008_4.csv-save-for-regression-testing; echo no differences: =$$!= 
    diff -q poalim report2008_4.csv; echo differences: =$$!= 

La primera 'diff' compara dos archivos iguales, y el segundo se comparan dos archivos diferentes. La salida es:

diff report2008_4.csv report2008_4.csv-save-for-regression-testing; echo no differences: =$!= 
no differences: == 
diff -q poalim report2008_4.csv; echo differences: =$!= 
Files poalim and report2008_4.csv differ 
differences: == 

Así que, obviamente '$$!' es la variable incorrecta para capturar el código de estado de 'diff'. Incluso usando SHELL: =/bin/bash al comienzo del Makefile no resolvió el problema.

Una variable que devuelve el valor, que necesito, se usaría (si es que existe) en un comando 'if' en la regla real.

La alternativa de crear un pequeño script de shell ad-hoc en lugar de escribir todos los comandos en línea en el Makefile no es deseable, pero lo usaré como último recurso.

relacionadas:

Respuesta

4

Uso '$$?' en lugar de '$$!' (gracias a la 4ta respuesta de Exit Shell Script Based on Process Exit Code)

+0

no puedo encontrar nada de '' $$ en el enlace que ya ha proporcionado!. Puede ser más específico modificando el URL y dando el que apunta directamente 'a la cuarta respuesta de Exit Shell Script Basado en Process Exit Code' usando el enlace' share' debajo de la 4ta respuesta si todavía está en el 4to posición – SebMa

0

La variable bash es $?, pero ¿por qué quiere imprimir el código de estado de todos modos?

-4

Pruebe `\ $? ' Creo que $$ está siendo interpretado por el archivo make

3

No olvide que cada uno de sus comandos se ejecuta en subcapas separadas.

Es por eso que a menudo se ve algo como:

my_target: 
    do something \ 
    do something else \ 
    do last thing. 

Y cuando la depuración, no se olvide de la opción -n todos los útiles que imprimirá los comandos pero no ejecutarlos y la opción -p, que se le mostrará el entorno de fabricación completo, incluido el lugar donde se han establecido las diversas partes y piezas.

HTH

aplausos,

+1

¿Por qué esta no es la respuesta aceptada? El póster original @Omer Zak está activo desde hace 2 días. Si bien no proporciona una respuesta de copiar y pegar, presenta con precisión la técnica necesaria para resolver el problema (Bash de varias líneas). –

34

pienso que usted está buscando la variable $? cáscara, lo que le da el código de salida del comando anterior.Por ejemplo:

$ diff foo.txt foo.txt 
$ echo $? 
0 

Para utilizar esto en su makefile, que tendría que escapar de la $, como en $$?:

all: 
    diff foo.txt foo.txt ; if [ $$? -eq 0 ] ; then echo "no differences" ; fi 

tenga en cuenta que cada comando en su cuerpo regla en el maquillaje se ejecuta en una subshell separada. Por ejemplo, el siguiente no funcionará:

all: 
    diff foo.txt foo.txt 
    if [ $$? -eq 0 ] ; then echo "no differences" ; fi 

Debido a que el diff y los comandos de if se ejecutan en diferentes procesos de concha. Si desea usar el estado de salida del comando, debe hacerlo en el contexto del mismo shell, como en mi ejemplo anterior.

+0

La motivación de $$ es útil. – Arun

+1

Normal 'diff foo.txt foo.txt && echo" sin diferencias "' se ve más delgado :) –

+0

ATENCIÓN: Observé que 'echo $$? ; 'provoca $$? para convertirse en 0 después del eco, probablemente porque el eco fue un éxito. Esto causó que mi sentencia if sea siempre cierta, para confirmar que probé 'echo $$ ?; echo $$ ?; 'en caso de errorlevel = 1 hace eco 1 luego 0 – SketchBookGames

2

Si estás pasando el código de resultado a un if, usted podría simplemente hacer:

all: 
    if diff foo.txt foo.txt ; then echo "no differences" ; fi 
Cuestiones relacionadas