2016-11-23 4 views
-1

Ich habe, was ich denke, ist eine seltsame hier. Ich habe folgende Umgebung.Linux kompilierte binäre bekommen falschen exit code wenn Ctrl + C eingegeben von einem Shell-Skript gestartet von der binären

  • Ein Linux kompiliert binäre, die ein Signal-Handler-Sets bis deaktivieren Dinge wie Strg + C, Strg + z, usw. Dies wird durch Rufsignal an getan wird: SIGINT, SITTSTP und SIGQUIT. Der Signalhandler gibt einfach eine Fehlermeldung aus, dass der Benutzer das Programm nicht abbrechen darf.
  • Nach dem Einrichten des Signalhandlers ruft die Binärdatei ein interaktives Asch-Skript auf.
  • Dieses interaktive Ash-Skript ALSO deaktiviert alle Methoden des Ausbrechens des Skripts. Es tut dies mit "Trap '' INT TSTP" ganz am Anfang. Das funktioniert, und wenn man Strg + C, usw. eingibt, wird einfach das Steuerzeichen an das Terminal gesendet, aber es wird nicht beendet.

Einzeln sowohl die Binär-und Asch-Skript verhindern Benutzer austreten.

jedoch bemerken, was unten passiert:

  1. ermöglichen die Steuerung der binären durch normale Beendigung des interaktiven Shell-Skript zurückgegeben werden. Sobald die Steuerung zu der Binärdatei zurückkehrt, funktioniert die Eingabe von Strg + C, und der Benutzer kann nicht aus dem Programm ausbrechen. Das ist richtiges Verhalten.

Wo es falsch ist, ist:

  1. Typ ein paar Strg + C die während der Zeit der interaktive Shell-Skript ausgeführt wird und sobald die Steuerung kehrt zu dem binären, der Ausgang Der Code wird in etwas anderes als das, was das Shell-Skript tut, geändert. Hier

ist ein Beispiel:

In C-Code, lassen Sie uns sagen, ich habe:

void sigintHandler(int sig_num) 
{ 
    fprintf(stderr, "You are not allowed to exit this program.\n"); 
    return; 
} 
void main(void) 
{ 
    signal(SIGINT, sigintHandler); 
    int ret = system("/etc/scripts/test.sh"); 
    printf("test.sh returned: %d exit status.\n", ret); 
} 

Und in test.sh ich habe:

#!/bin/ash 
# Disable interrupts so that one cannot exit shell script. 
trap '' INT TSTP 
echo -n "Do you want to create abc file? (y/n): " 
read answer 
if [ $answer == "y" ];then 
    touch /tmp/abc 
fi 
if [ -f /tmp/abc ]; then 
    echo "Returning 1" 
    exit 1 
else 
    echo "Returning 2" 
    exit 2 
fi 

Wenn ich das laufen C binary normalerweise bekomme ich den richtigen Ausgangsstatus (1 oder 2) abhängig davon, ob die Datei existiert. Tatsächlich bekomme ich 256 oder 512, was anzeigt, dass der Exit-Code im 2. Byte gespeichert wird. Punkt ist, dass dies jedes Mal konsistent funktioniert.

Aber jetzt, wenn ich Ctrl + C während das Shell-Skript läuft (vor der Beantwortung der Frage) und sagen, ich antworte "n", was ist der Exit-Code von 2. In der C-binäre der Code, den ich manchmal zurück 2 (nicht 512, zeigt an, dass der Exit-Code jetzt im LOWER-Byte ist), aber MORE oft bekomme ich einen Code von 0 zurück! Dies geschieht, obwohl ich die Meldung "Returning 2" (Rückkehr 2) erhalte, die vom Shell-Skript wiederholt wird.

Dies macht mich verrückt zu versuchen, herauszufinden, warum eine einfache Exit-Code wird versaut.

Kann jemand einige Vorschläge machen?

Dank viel Allen

+0

[Mann-System] (http://man7.org/linux/man-pages/man3 /system.3.html): "Der Rückgabewert ist ein" Wartezustand ", der unter Verwendung der in waitpid (2) beschriebenen Makros untersucht werden kann (dh WIFEXITED(), WEXITSTATUS() und so weiter)." – kaylum

+0

Erscheinen die gleichen Symptome bei verschiedenen Shells? (z. B. #!/bin/bash, #!/bin/sh, #!/bin/dash, #!/bin/ksh usw.) –

+0

@ kaylum WIFSIGNALED gab wahr zurück und WTERMSIG gab 2 zurück, was SIGINT ist. Das Problem ist jedoch, dass dieser Interrupt deaktiviert ist, sodass das Shell-Skript NICHT beendet wurde. Dies passiert, wird sh, Asche und bash. Ich habe die anderen nicht installiert. Dank Allen –

Antwort

0

fand ich das Problem.

Früher habe ich Trap '' INT TSTP verwendet, um Interrupts im Shell-Skript zu deaktivieren. Dies verhindert zwar, dass das Shell-Skript abgebrochen wird, führte jedoch in diesem Beitrag zum Problem. Ich vermute, dass das Shell-Framework der oberen Ebene dies nicht wusste und dass es wusste, dass Ctrl + C oder was auch immer gedrückt wurde und SIGINT als Exit-Code trotz der Shell zurückgegeben wurde Das Skript selbst war aufregend.

Die Lösung ist zu verwenden: -isig

stty

am Anfang des Shell-Skript.

Dies deaktiviert nicht nur Interrupts, sondern ALSO lässt das Framework der oberen Ebene wissen, dass Sie dies getan haben, so dass es die Tatsache ignoriert, dass Strg + C gedrückt wurde.

ich diese Informationen auf der folgenden Seite:

https://unix.stackexchange.com/questions/80975/preventing-propagation-of-sigint-to-parent-process

Vielen Dank allen, Allen

Verwandte Themen