2017-11-01 2 views
1

nur eine kurze Frage mit etwas, das ich nicht verstehe. Alles funktioniert gut - ich versuche nur, mich um etwas zu kümmern.Problem in einer Bash-Schleife

Ich habe ein sehr einfaches Bash-Skript, das dnsmasq einmal pro Tag neu gestartet wird:

LogFile="/var/log/logfile" 
declare -a CMD_AR=() 
declare -a ECHO_OUT=(stopping starting) 
STOP=$(service dnsmasq \stop) 
SLEEP=$(\sleep 15) 
START=$(service dnsmasq \start) 
CMD_AR+=($STOP) 
CMD_AR+=($START) 

z=0 
while [[ $z -le 1 ]]; do 
     DT=`date +%c` 
     echo "$DT - ${ECHO_OUT[$z]} dnsmasq..." >> ${LogFile} 
     eval ${CMD_AR[$z]} >> ${LogFile} 2>&1 
     unset DT 
     eval ${SLEEP} 
     z=$[$z+1] 
done 

So ... das funktioniert, die DT-Variable nie ändert sich jedoch. Also meine Protokolldatei lautet:

Tue 31 Oct 2017 10:57:07 PM MDT - stopping dnmasq 
Tue 31 Oct 2017 10:57:07 PM MDT - starting dnmasq 

Sollte nicht die Zeit Zeichenfolge mindestens 15 (der Wert von Schlaf 15) Sekunden anders sein? Ich verstehe nicht, warum die Schleife die DT-Variable nicht neu berechnet - irgendjemand?

Auch nehme ich irgendwelche Vorschläge zu meinem Code - ich bin ein totaler Hack, wenn es um Scripting geht.

+0

während [[$ z -l e 1]]; tun <- ist dies absichtlich können Sie vermeiden, wenn dies beabsichtigt ist, BTW SLEEP = $ (\ Schlaf 15) => SLEEP = "Schlaf 15" –

Antwort

3

Das Problem ist in dieser Zeile:

SLEEP=$(\sleep 15) 

, die seit dem Befehl SLEEP-Variable auf einen Null-String setzt sleep 15 erzeugt keine Ausgabe.

Ändern Sie es an:

SLEEP="sleep 15" 

Ihr Problem zu lösen.

Die Linie

START=$(service dnsmasq \start) 

hat das gleiche Problem.


Ihr Skript scheint zu kompliziert - bekommen sie durch shellcheck geprüft. Im Allgemeinen ist es keine gute Idee, Befehle in einer Variablen zu speichern und sie über eval auszuführen - siehe BashFAQ/050. Ihr Code kann auf diese Weise neu geschrieben werden:

LogFile="/var/log/logfile" 
z=0 
while ((z <= 1)); do 
    if ((z == 0)); then 
     echo "$(date) - stopping dnsmasq..." >> "${LogFile}" 
     service dnsmasq stop >> "${LogFile}" 2>&1 
    else 
     echo "$(date) - starting dnsmasq..." >> "${LogFile}" 
     service dnsmasq start >> "${LogFile}" 2>&1 
    fi 
    sleep 15 
    ((z++)) 
done 

Verbesserungen gemacht:

  • Verwenden ((..)) für arithmetische Operationen und Kontrollen
  • Wrap Variablen in doppelten Anführungszeichen Wort Spaltung
  • entfernen indirekte Ausführung zu verhindern, mit eval
  • Eliminieren Sie das Array - wir brauchen es hier nicht
  • Machen Sie den Code lesbarer

Die Schleife scheint hier unnötig. Der Code könnte wahrscheinlich noch prägnanter geschrieben werden als:

LogFile="/var/log/logfile" 
exec >"$LogFile" 2>&1 
echo "$(date) - stopping dnsmasq..." 
service dnsmasq stop 
sleep 15 
echo "$(date) - starting dnsmasq..." 
service dnsmasq start 
+1

OK, danke - Ja, ich weiß, dass es ein bisschen kompliziert ist, ich nur Habe das Array nur gemacht, um es wirklich zu tun - es ist auch nicht alles, was es für mein Skript gibt, also hatte ich das Array bereits definiert - aber es ist definitiv zu viel. Ich hatte auch den Eindruck, dass es ratsam war, eval zu verwenden - tatsächlich hatte ich ursprünglich "Dienst dnsmasq Neustart" und während es funktionierte, bekam ich gelegentlich eine Fehlermeldung im Protokoll über "bad command". Trotzdem, vielen Dank für die Hilfe - wie ich schon sagte, ich bin ein newb -Josh –

+0

Oh, und danke für den Befehl exec - das ehrfürchtige ist und shellcheck :) –

+0

Glad es half. [Was tun, wenn jemand meine Frage beantwortet] (https://stackoverflow.com/help/someone-answers). – codeforester

Verwandte Themen