2009-04-14 12 views
17

J'utilise un Makefile (avec GNU make fonctionnant sous Linux) pour automatiser mon travail de base lors de la refactorisation d'un script Python. Le script crée un fichier de sortie, et je veux m'assurer que le fichier de sortie reste inchangé face à mes refactorings.Les codes d'état du shell en make

Cependant, je n'ai trouvé aucun moyen d'obtenir le code d'état d'une commande pour affecter une prochaine commande shell.

La règle suivante illustre le problème:

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: =$$!= 

Le premier « diff » compare deux fichiers égaux, et le second compare deux fichiers différents. La sortie est:

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: == 

Alors, évidemment, '$$! est la mauvaise variable pour capturer le code d'état de 'diff'. Même en utilisant SHELL: =/bin/bash au début du Makefile n'a pas résolu le problème.

Une variable renvoyant la valeur dont j'ai besoin serait (si elle existe) utilisée dans une commande 'if' dans la règle réelle.

L'alternative de créer un petit script shell ad-hoc au lieu d'écrire toutes les commandes en ligne dans le Makefile n'est pas souhaitable, mais je vais l'utiliser en dernier recours.

connexes:

Répondre

4

utilisation $$? au lieu de '$$!' (Merci à la 4ème réponse de Exit Shell Script Based on Process Exit Code)

+0

Je ne trouve rien '' $$ dans le lien que vous avez fourni!. Pouvez-vous être plus précis en modifiant l'URL et en donnant directement la réponse à la 4ème réponse de Exit Shell Script basé sur le code de sortie du processus en utilisant le lien 'share' sous la 4ème réponse s'il est encore au 4ème position – SebMa

0

La variable bash est $?, mais pourquoi voulez-vous imprimer le code d'état de toute façon?

-4

Essayez `\ $? ' Je pense que le $$ est interprété par le makefile

3

N'oubliez pas que chacune de vos commandes est exécutée dans des sous-cases distinctes.

C'est pourquoi vous voyez souvent tout à fait quelque chose comme:

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

Et quand le débogage, ne pas oublier l'option every -n utile qui imprimera les commandes mais pas les exécuter et l'option -p qui sera vous montrer l'environnement de fabrication complet, y compris où les différents morceaux ont été définis.

HTH

acclamations,

+1

Pourquoi n'est-ce pas la réponse acceptée? L'affiche originale @Omer Zak est active depuis 2 jours. Bien qu'il ne fournisse pas de réponse copier-coller, il présente avec précision la technique nécessaire pour résoudre le problème (Bash multi-lignes). –

34

Je pense que vous cherchez la variable shell $?, ce qui donne le code de sortie de la commande précédente.Par exemple:

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

Pour utiliser dans votre makefile, vous devez échapper à la $, comme dans $$?:

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

Prenez note que chaque commande dans votre corps de règle make est exécuté en un sous-shell séparé. Par exemple, ce qui suit ne fonctionnera pas:

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

Parce que le diff et les if commandes sont exécutées dans différents processus shell. Si vous voulez utiliser l'état de sortie de la commande, vous devez le faire dans le contexte du même shell, comme dans mon exemple précédent.

+0

La motivation de $$ est utile. – Arun

+1

Plain 'diff foo.txt foo.txt && echo" pas de différences "' semble plus mince :) –

+0

ATTENTION: J'ai observé que 'echo $$? ; 'provoque $$? pour devenir 0 après l'écho, probablement parce que l'écho était un succès. Cela a provoqué que mon instruction if soit toujours vraie, pour confirmer que j'ai testé 'echo $$? echo $$ ?; 'en cas de errorlevel = 1 il fait écho 1 puis 0 – SketchBookGames

2

Si vous passez le code de résultat à un if, vous pouvez simplement faire:

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