zatrzymanie skryptu python z poziomu web

Odpowiedz Nowy wątek
2016-11-20 12:26

Rejestracja: 4 lata temu

Ostatnio: 7 miesięcy temu

0

Cześć,

Mam przygotowaną stronę z poziomu której mogę uruchomić skrypt w pythonie, natomiast problem jest zatrzymanie skryptu.
Zatem po kolei
Funkcja JQuery uruchamia mi skrypt w php z jakimiś parametrami :


 $.get(
    $('#sensor').click(function() {
              if (s == 0) {
              //    $('#sensor').css("background", "url(img/pause.png)");
                  s = 1;
                  sensormode = 'stop'
              } else {
              //    $('#sensor').css("background", "url(img/play.png)");
                  s = 0;
                  sensormode = 'start'
              }

                $.get("control.php", {
                   mode: 'sensor',
                   sMode: sensormode
                }, function(data) {});
            }); //sensor

Skrypt php uruchamia mi z kolei skrypt w pythonie:

}elseif ($mode == 'sensor'){
    $x = $_GET['sMode'];
    system("sudo python2 sensor.py ".$x);
}

Tak wygląda sensor.py


  if sys.argv[1] == 'start':

           if i==1:             

                  (...)

  elif sys.argv[1] == 'stop':
      sys.exit()

Jak mówiłem, uruchamia się prawidłowo, nie mogę go tylko zatrzymać. Jakieś sugestie?

Pozostało 580 znaków

2016-11-20 12:54

Rejestracja: 4 lata temu

Ostatnio: 1 dzień temu

1

Po pierwsze nieświadomie utworzyłeś takie dziursko, że głowa mała. Dajesz każdemu możliwość wykonania dowolnej komendy na twoim serwerze.

$x = $_GET['sMode']; // załóżmy, że $_GET['sMode'] === '&& sudo rm -rf  --no-preserve-root /'
system("sudo python2 sensor.py ".$x);

Po drugie z tego co się orientuje, to w momencie wykonania sudo python2 sensor.py po raz drugi odpalasz całkowicie nowy proces, który po prostu wykonuje sys.exit() i tyle. Pierwszy proces cały czas sobie działa. W ten sposób nie zatrzymasz procesu odpalonego z poprzedniego wywołania.

Zamiast cudować z system i sudo użyj systemu wiadomości, np. rabbitmq.

edytowany 3x, ostatnio: Desu, 2016-11-20 12:59

Pozostało 580 znaków

2016-11-20 20:15

Rejestracja: 4 lata temu

Ostatnio: 7 miesięcy temu

0

No nie tak do końca nieświadomie, musiałem przecież zezwolić userowi www-data odpalać skrypt jako sudo bez podawania hasła(/etc/sudoers).
Projekcik tworze tylko dla własnych potrzeb więc pozwoliłem sobie na tego typu brutal force z świadomością zagrożenia, zresztą przy obecnej metodzie z łatwością poradzę sobie z zasugerowanym niebezpieczeństwem.
Może faktycznie RabbitMQ jest dobrym rozwiązaniem, tym bardziej że w niedługim czasie planuje zająć się node.js (jak już oswoję się z javascript), może jednak masz(lub ktoś inny) pomysł na rozwiązanie tego problemu bez konieczności doktoryzowania się w nowej dla mnie technologi?

"musiałem przecież zezwolić userowi www-data odpalać skrypt" - okej ale odpalenie skryptu to jedno, a wstrzykiwanie parametru z geta to drugie. Mogłes przecież zrobić dwa warunki, że jeżeli cos to stop a jezeli cos innego to start, bez wstrzykiwania zmienny z $_GET! - Desu 2016-11-21 07:51

Pozostało 580 znaków

2016-11-21 00:12

Rejestracja: 6 lat temu

Ostatnio: 21 godzin temu

0

Można użyć pkill, poniżej mały poc

marek2:~/workspace $ cat p.py 
while True:
  pass
marek2:~/workspace $ python p.py &
[1] 2518
marek2:~/workspace $ ps
    PID TTY          TIME CMD
    586 pts/1    00:00:00 bash
    587 pts/1    00:00:00 bash
   2518 pts/1    00:00:02 python
   2522 pts/1    00:00:00 ps
marek2:~/workspace $ pkill -f "python p.py"
[1]+  Terminated              python p.py

Pozostało 580 znaków

Zimny Lew
2016-11-21 06:02
Zimny Lew
0

proc_open z php wywołuje "sh -c", a nastepnie proces docelowy.
php -> sh -c -> PROCES
Można użyć coś takiego tylko trzeba mieć pewność, że PROCES utworzy się o PID + 1 względem procesu sh -c.

<?php
$desc = array(
    0 => array("pipe","r"),
    1 => array("pipe","w"),
    2 => array("pipe","w")
);
$cwd = '/sciezka/do/katalogu/w/ktorym/ma/byc/uruchomiony/proces/';
$proc = proc_open('/proces/do/uruchomienia',$desc,$pipes,$cwd);
if(is_resource($proc)){
    $a = proc_get_status($proc);
    $pid = $a['pid'];
    $pid += 1;
    sleep(5);
    system("kill $pid");  # system("kill -KILL $pid"); dla opornych
    fclose($pipes[0]);
    fclose($pipes[1]);
    fclose($pipes[2]);
}
?>

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0