2015-06-12 10 views
8

I wie unten unter Verwendung einer Funktion system() Bibliotheksfunktion codiert haben:System() gibt gelegentlich 2

#!/bin/sh 
PATH=$PATH:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin 
cd $(dirname $0) 

agent_name=`grep 'agent_name' ../etc/config.ini |awk '{ print $3 }'` 
py='../../python26/bin/python' 

check_alive() 
{ 
    status=`ps -ef | grep "$agent_name" | grep -v "grep" |wc -l` 

    if [ $status -ne 0 ]; then 
     # process exist 
     echo "$agent_name already exist" 
     exit 1 
    fi  

} 

check_alive 
eval '$py ../bin/agent.py -d' 

status=`ps -ef | grep "$agent_name" | grep -v "grep" |wc -l` 
if [ $status -lt 1 ] 
then 
    echo "run failed" 
    exit -1 
else 
    echo "run succ" 
    exit 0 
fi 

Aber manchmal gibt:

int execute(const char* cmd) 
{ 
    int ret = system(cmd); 

    if (ret != -1) 
    { 
    if (WIFEXITED(ret)) 
     ret = WEXITSTATUS(ret); 
    else 
     ret = -1; 
    } 

    LINFO("execute %s, ret = %d", cmd, ret); // logging 
    return ret; 
} 

Dann habe ich es mit einem Shell-Skript, wie unten genannt war ein ungeraden Rückkehrcode von 2, wie unten:

[INFO]execute ./admin/trystart.sh, ret = 1 
[INFO]execute ./admin/trystart.sh, ret = 1 
[INFO]execute ./admin/trystart.sh, ret = 2 
[INFO]execute ./admin/trystart.sh, ret = 2 
[INFO]execute ./admin/trystart.sh, ret = 1 
[INFO]execute ./admin/trystart.sh, ret = 1 
[INFO]execute ./admin/trystart.sh, ret = 1 
[INFO]execute ./admin/trystart.sh, ret = 1 
[INFO]execute ./admin/trystart.sh, ret = 1 
[INFO]execute ./admin/trystart.sh, ret = 2 

Ich möchte verstehen, warum dort ein Return-Code von 2 war

================ neue 2015.06.12 13.54 ============== ==============

ich habe festgestellt, dass, wenn das System() 2 ergibt, gibt eine Fehlermeldung aus, wie unten bash war:

bash: xmalloc: locale.c:73: cannot allocate 2 bytes (0 bytes allocated) 
+0

Dies ist eine sehr gut formatiert Frage. Keine Verbesserung benötigt. Nur als Randnotiz kann der Grund hinter "return ret" stehen, wobei "ret = system (cmd)". 'system (cmd)' könnte äqusl '2' sein. – HyperNeutrino

+0

@JamesSmith Wenn 'system' zurück '2' dann würde er traf den'! = -1' Fall und 'WIFEXITED' sollte false zurück und' ret' auf 'gesetzt werden soll -1' glaube ich. –

+0

Als beiseite. Suchen Sie in Ihrer Pipeline nach 'pgrep' und das 'eval' ist völlig unnötig. –

Antwort

8

der Statuscode von 2 wird von deiner Shell zurückgegeben. Ohne viel mehr Details wird es schwierig sein zu diagnostizieren. Das Hinzufügen der tatsächlichen Fehlermeldung, die von der Shell erzeugt wurde, war nützlich.

Wenn Sie Shell ist bash - wie es jetzt zu sein scheint - dann ist der Status Return-Code von 2 zeigt eine Fehlerspeicherzuweisung, die durch die Fehlermeldung durch bash erzeugt bestätigt:

bash: xmalloc: locale.c:73: cannot allocate 2 bytes (0 bytes allocated) 

Zeile 73 ist, soweit ich sehen kann, die erste Speicherzuweisung, die von einem neu gestarteten bash Prozess ausgeführt wurde (was durch die Fehlermeldung bestätigt wird, dass noch keine Bytes zugewiesen wurden), so dass es wahrscheinlich das Problem ist malloc kann keinen Speicher zuordnen.

Es ist möglich, dass wirklich kein Speicher verfügbar ist, insbesondere wenn Sie auf einem stark ausgelasteten System arbeiten, auf dem kein Swap konfiguriert ist. Aber es gibt ein paar Hinweise im Internet, die darauf hinweisen, dass dies mit Speicherschutzoptionen zu tun haben könnte; insbesondere Konfigurationen, in denen sbrk nicht verfügbar ist, aber die malloc-Bibliothek erwartet, dass sie in der Lage ist, sie zu verwenden.

Vielleicht möchten Sie weitere Diagnose starten, indem Sie prüfen, ob es möglich ist, zuverlässig neue Schalen zu starten:

for i in {0..999}; do sh -c 'exit 0' || echo Failure $?; done 

Eine frühere Vermutung, die sonst von Nutzen jemand sein könnte. Die Behebung des Aufrufs von exit wird empfohlen, obwohl es wahrscheinlich nichts mit dem speziellen Problem in dieser Frage zu tun hatte.

Die dash-Shell, die als /bin/sh Implementierung von einer Reihe von Verteilungen verwendet wird, gibt den Statuscode 2 zurück, wenn die Shell aufgrund eines Fehlerzustands beendet wird.

Eine mögliche Täter aus dem obigen Skript ist

exit -1 

Status-Rückgabecodes Acht-Bit-Werte ohne Vorzeichen sind; Mit anderen Worten, die zulässigen Rückgabecodes liegen im Bereich von 0 bis 255. -1 liegt nicht in diesem Bereich, und Sie sollten sie nicht in einem Aufruf an 10 verwenden.

Bash exit builtin (wie die Funktion C exit) verwendet einfach die niederwertige Byte des Returncodes geliefert, so mit bash würden Sie einen Return-Code von 255 gesehen haben, aber der Strich gebautet exit erwartet ihr Argument eine sein vorzeichenlose Nummer und beschwert sich, dass -1 keine gültige Nummer ist.

Da ein Spezial-Built-in ist und die Shell nicht interaktiv ist, verursacht der Fehler, dass die Shell beendet wird, wie in the Posix standard. Dash setzt den Exit-Code auf 2, wenn es aufgrund eines Shell-Fehlers beendet wird.

+0

Ah, dachte ich, dass die 255 abgeschnitten wurde, bevor es angemeldet wurde. Das macht mehr Sinn. –

+0

Aber selbst wenn ich den Inhalt des Skripts ./admin/trystart.sh nur 'exit 1' zurücksetzen, passiert das Problem erneut. – Hetiu

+0

Ich habe festgestellt, dass, wenn das System() 2 ergibt, gibt es eine Fehlermeldung von bash wie es: "bash: xmalloc: locale.c: 73: 2 Byte nicht zuordnen kann (0 Bytes zugeteilt)" – Hetiu