Как завершить бесконечный цикл while в коде bash из другого кода python?

#python-3.x #infinite-loop #terminate

#python-3.x #бесконечный цикл #завершить

Вопрос:

представьте себе следующий бесконечный цикл while:

 #!/bin/bash
i=0
while true; do
   echo $i
   i=$((i 1))
done
  

Я запускаю этот код из кода Python, подобного этому:

 def start(self):
  filepath = '/home/sysop/.seiscomp3/program.sh'
  if os.path.exists(filepath):
     Command = "gnome-terminal -e '/home/alireza/.seiscomp3/program.sh'"
     proc = subprocess.Popen(['bash','-c', Command])
  else:
     print ("The executable file is missing. Check ~/.seiscomp3 directory ...")
def stop(self):
   proc.terminate()
  

приведенный выше код python работает с другой программой (назовем ее SC3) и запускает / останавливает приведенный выше код bash в новом терминале. Когда я запускаю программу SC3, она должна запускать функцию «start» в приведенном выше коде python.(который работает нормально). Но проблема заключается в функции stop, которая должна останавливать код bash, запущенный в подпроцессе.
Мой вопрос в том, как я могу завершить этот новый терминал и его процесс?

Комментарии:

1. Я думаю, проблема в том, что PID подпроцесса, созданный в функции «start», недоступен из функции «stop»… Есть идеи?

Ответ №1:

В настоящее время вы запускаете дополнительные процессы, что мешает перехватить правильный процесс в качестве возврата из Popen.

Если возможно, запустите

 proc = subprocess.Popen(['bash', '/home/alireza/.seiscomp3/program.sh'])
  

должно быть более прямым и позволять вам фиксировать правильный процесс, что сделает остальную часть ответа полезной.


Учитывая, что вы переходите self к функциям start и stop, это наводит меня на мысль, что это методы объекта. Если вы можете сохранить дескриптор процесса, который вы создали в этом объекте, в новом поле, это позволит вам извлечь его обратно для использования в функции stop.

 
def start(self):
    filepath = '/home/sysop/.seiscomp3/program.sh'

    # Just in case the path doesn't exist
    self.proc = None

    if os.path.exists(filepath):
        Command = "gnome-terminal -e '/home/alireza/.seiscomp3/program.sh'"

        # Assign to the internal field proc
        self.proc = subprocess.Popen(['bash','-c', Command])
    else:
        print ("The executable file is missing. Check ~/.seiscomp3 directory ...")

def stop(self):
    # Make sure that the object has the proc field (It should if it has been started.)
    # AND
    # Only try to terminate if there is a process running
    if('proc' in dir(self) and self.proc):
        self.proc.terminate()

  

Если они не являются методами, вы могли бы вернуться proc из функции start и передать его в функцию stop.

 
start():
    # Do stuff
    return proc

stop(proc):
    proc.terminate()
  

Комментарии:

1. Спасибо за ваше предложение, но оно выдает мне ошибку «ошибка: не удалось остановить: экземпляр модуля не имеет атрибута ‘proc'».

2. Мне интересно, почему, но когда я получаю PID подпроцесса с помощью команды «PiD = proc.pid», а затем пытаюсь уничтожить его вручную в терминале «kill -9 $ PiD», он не смог найти PID для уничтожения!

3. Как вы сказали, это некоторые методы для программного обеспечения SC3. Но ни одно из ваших предложений не работает! та же ошибка

4. Извините, я думаю, что неправильно рассмотрел проблему. То, что вы делаете, это запуск дополнительных процессов; процесс bash, который запускает процесс gnome-terminal, который запускает процесс, который запускает ваш скрипт bash.