Ich habe ein Python-Skript, das Bash-Skripte ausführt. Ich muss in der Lage sein, das Bash-Skript zu töten, wenn es unendlich zu sein scheint, und es muss auch im Chroot-Gefängnis laufen, weil das Skript gefährlich sein könnte. Ich lasse es mit psutil.Popen()
laufen und lasse es für zwei Sekunden laufen. Wenn es nicht natürlich endet, sende ich SIGKILL
an es und all seine möglichen Kinder.Linux - Gründe für SIGSTOP und wie man damit umgeht?
Das Problem ist, dass das Haupt (Python) -Skript eine SIGSTOP
empfängt, wenn ich ein Skript wegen Überstundenausführung abbringe und ein anderes ausführe. Auf meinem lokalen Rechner habe ich eine wirklich dumme Lösung gemacht: Das Python-Skript schrieb seine PID beim Start in eine Datei und dann lief ich ein weiteres Skript, das jede Sekunde SIGCONT
an die PID sendete, die in der Datei gespeichert war. Dies hat zwei Probleme: Es ist wirklich dumm, aber noch schlimmer ist, dass es sich weigert, auf dem Server zu arbeiten - SIGCONT
macht einfach nichts.
Die Sequenz ist: Python-Skript läuft ein Bash-Skript reagiert für die Jail und das Bash-Skript führt die möglicherweise gefährliche und/oder unendliche Skript. Dieses Skript könnte auch einige Kinder haben.
Die relevanten Teile der Codes:
Haupt Python-Skript
p = psutil.Popen(["bash", mode, script_path, self.TESTENV_ROOT])
start = time.time()
while True:
if p.status() == psutil.STATUS_ZOMBIE:
# process ended naturally
duration = time.time() - start
self.stdout.write("Script finished, execution time: {}s".format(duration))
break
if time.time() > start + run_limit:
children = p.children(recursive=True)
for child in children:
child.kill()
p.kill()
duration = None
self.stdout.write("Script exceeded maximum time ({}s) and was killed.".format(run_limit))
break
time.sleep(0.01)
os.kill(os.getpid(), 17) # SIGCHLD
return duration
Ausführen von Script in chroot ($ 1 ist das Skript in der chroot-Umgebung ausgeführt werden, ist 2 $ das Gefängnis Pfad)
#!/usr/bin/env bash
# copy script to chroot environment
cp "$1" "$2/prepare.sh"
# run script
chmod u+x "$2/prepare.sh"
echo './prepare.sh' | chroot "$2"
rm "$2/prepare.sh"
Beispiel prepare.sh Skript
#!/bin/bash
echo asdf > file
verbrachte ich einige Zeit versucht, das Problem zu lösen. Ich fand heraus, dass dieses Skript (die nicht chroot-Gefängnis wird mit Bash-Skripte ausgeführt werden) funktioniert perfekt:
import psutil
import os
import time
while True:
if os.path.exists("infinite.sh"):
p = psutil.Popen(["bash","infinite.sh"])
start = time.time()
while True:
if p.status() == psutil.STATUS_ZOMBIE:
# process ended naturally
break
if time.time() > start + 2:
# process needs too much time and has to be killed
children = p.children(recursive=True)
for child in children:
child.kill()
p.kill()
break
os.remove("infinite.sh")
os.kill(os.getpid(), 17)
Meine Fragen sind:
- Warum erhalte ich
SIGSTOP
s? Liegt es am Chroot-Gefängnis? - Gibt es einen besseren Weg, mein Problem zu lösen, als das "Wake Up" -Skript auszuführen?
Vielen Dank für Ihre Ideen.
EDIT: Ich fand heraus, dass ich in dem Moment sigstopped bin, in dem ich das erste Skript lief, nachdem ich eine Überstunden getötet habe. Egal ob ich os.system
oder psutil.Popen
verwende.
EDIT2: Ich habe noch mehr Untersuchung und die kritische Linie ist echo './prepare.sh' | chroot "$2"
in der Bash-Skript Kontrolle der Chroot-Gefängnis. Die Frage ist jetzt, was zum Teufel ist los damit?
EDIT3:This könnte ein verwandtes Problem sein, wenn es jemandem hilft.
Können Sie dieses 'prepare.sh' Skript posten? – ElmoVanKielmo
hat meinen Beitrag bearbeitet. – karlosss