2009-07-13 10 views
1

J'ai un script bash qui extrait le contenu d'un autre fichier. Le contenu de l'autre fichier sont des commandes que j'aimerais exécuter et comparer la valeur de retour. Certaines des commandes ont plusieurs commandes séparées par un point-virgule (;) ou par des esperluettes (& &) et je n'arrive pas à faire fonctionner cela. Pour travailler, je créé des scripts de test comme indiqué:BASH Variables avec plusieurs commandes et réentrantes

test.conf est le fichier en cours d'origine par le test

Exemple-1 (cela fonctionne), Ma sortie est de 2 secondes dans la différence

test.conf

 
    CMD[1]="date" 

test.sh

 
    . test.conf 
    i=2 
    echo "$(${CMD[$i]})" 
    sleep 2 
    echo "$(${CMD[$i]})" 

Exemple-2 (cela ne fonctionne pas) test.conf (même script comme ci-dessus)

 
    CMD[1]="date;date" 

Exemple-3 (essayé, ça ne marche pas non plus) test.conf (même script comme ci-dessus)

 
    CMD[1]="date && date" 

Je ne Je veux que ma variable, CMD, soit à l'intérieur des graduations car alors, les commandes seraient exécutées au moment de l'invocation de la source et je ne vois aucun moyen de réévaluer la variable.

Ce script appelle essentiellement CMD sur pass-1 pour vérifier quelque chose, si sur pass-1 j'obtiens une fausse lecture, je fais un peu de travail dans le script pour corriger la fausse lecture et ré-exécuter & ré-évaluer la sortie de CMD; pass-2.

Voici un exemple. Ici, je vérifie pour voir si SSHD est en cours d'exécution. Si ce n'est pas le cas lorsque j'évalue CMD [1] sur pass-1, je vais le démarrer et réévaluer CMD [1] à nouveau.

test.conf

 
    CMD[1]=`pgrep -u root -d , sshd 1>/dev/null; echo $?` 

Donc, si je modifie pour mon script de test, puis devient test.conf: REMARQUE: des marques ne se présentent pas, mais il est la clé sous la barre ~ sur mon clavier .

 
    CMD[1]=`date;date` or `date && date` 

Mon script ressemble à ceci (pour gérer les marques de tiques)

 
    . test.conf 
    i=2 
    echo "${CMD[$i]}" 
    sleep 2 
    echo "${CMD[$i]}" 

Je reçois la même date/heure imprimée deux fois malgré le délai de 2 secondes. En tant que tel, CMD ne réévalue pas.

+1

Votre question n'est pas clair - en fait, je ne vois pas la question. Qu'est-ce que vous essayez exactement de faire, et où ça va mal? Votre "exemple", "test.conf CMD [1] = pgrep -u" ... n'a que peu de sens - où est le "fichier source"? Comment analysez-vous les arguments - il vous manque des citations comme je le vois? –

+0

Ceci est un script de test, pas le réel. D'où la raison pour laquelle le $ i est toujours là (coupé-passé) et cela manque de clarté. Le CMD [x] où x = 0 ... 10 sont des conditions de test qui renvoient 1 ou 0; La plupart du temps le processus est en cours ou non et similaire à l'exemple de pgrep donné ci-dessus. Avec CMD, j'ai un RESTART [x] correspondant que j'appelle et après que je l'appelle, je réévalue le CMD [x] pour voir si le processus a redémarré. Dans d'autres exemples, je vérifie la présence d'un fichier journal. Je ne voulais pas ennuyer le forum avec ces détails, mais cela aurait probablement été utile. Merci! – Eric

Répondre

1

Tout d'abord, vous ne devez jamais utiliser des accents graves, sauf si vous avez besoin d'être compatible avec une vieille coquille cela ne prend pas en charge $() - et seulement alors.

Deuxièmement, je ne comprends pas pourquoi vous configurez CMD[1] mais appeler CMD[$i] avec i ensemble à 2.

Quoi qu'il en soit, c'est une façon (et il est similaire à une partie de la réponse de Barry):

CMD[1]='$(date;date)' # no backticks (remember - they carry Lime disease) 
eval echo "${CMD[1]}" # or $i instead of 1 
+0

Cela fonctionne également. Je n'avais pas pensé à cette méthode. Excellent merci! – Eric

1

Du quelques lignes de votre question, je me serais attendu à une approche comme celle-ci:

#!/bin/bash 

while read -r line; do 
    # munge $line 
    if eval "$line"; then 
     # success 
    else 
     # fail 
    fi 
done 

Si vous avez backticks dans la source, vous devrez leur échapper pour éviter de les évaluer trop tôt . En outre, les backticks ne sont pas le seul moyen d'évaluer le code - il y a eval, comme indiqué ci-dessus. C'est peut-être eval que vous cherchiez?

Par exemple, cette ligne:

CMD[1]=`pgrep -u root -d , sshd 1>/dev/null; echo $?` 

Fallait-chercherais probablement plus comme ceci:

CMD[1]='`pgrep -u root -d , sshd 1>/dev/null; echo $?`' 
+0

Cela fonctionne! Cependant, par mes et vos commentaires précédents (nous sommes d'accord), je ne veux pas back ticks là-bas. Ce script ne vivra pas sur d'autres environnements en dehors de Linux, je n'ai aucun contrôle sur BASH et suis d'accord avec votre souci de portabilité! – Eric

Questions connexes