4

I am working on UBUNTU and I have file main.py with a code inside:

#!/usr/bin/env python3
# coding=utf-8
import os
import time
from subprocess import Popen, PIPE, call, signal

base_path = os.path.abspath('')
path_to_file = base_path + '/test_subprocess.py'
p = Popen(['gnome-terminal', "--",  path_to_file])
time.sleep(2)

os.kill(p.pid, signal.SIGKILL)

I have test_subprocess.py with code like that:

#!/usr/bin/env python3
# coding=utf-8

import time

def print_message():
    while True:
        print('I am working!')
        time.sleep(0.5)
    
print_message()

I tried to kill the subprocess but after

os.kill(p.pid, signal.SIGKILL)

subprocess is still working and prints 'I am working!'

How can I finish subprocess and how to close gnome terminal? If I selected completely wrong way. Can you show me working example?

New version of test_subprocess.py

#!/usr/bin/env python3
# coding=utf-8
import sys
from subprocess import signal
import time

def print_message():
    while True:
        print('I am working!')
        time.sleep(0.5)
        if signal.SIGKILL:  # it is braking a loop when parent process terminate!
            print('I am killing self!')
            break

print_message()

Should I do it like above?

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
luki
  • 197
  • 11
  • Does signal.SIGKILL in test_subprocess.py fix my problem? I have checked and it is closing subprocess. Is that all what i need? – luki May 02 '21 at 22:24
  • Please don't add additional questions (and answers) into the question. Each question page should be about a single question. Changing/adding your question might invalidate existing answers - please avoid that. If you have a new question, you can [ask another one](https://stackoverflow.com/questions/ask) – Tomerikoo May 03 '21 at 18:19

2 Answers2

1

You could try the following:

p = Popen(['gnome-terminal', "--",  path_to_file])
PIDs = p.pid
os.system("kill {0}".format(PIDs))

Popen.pid The process ID of the child process.

Note that if you set the shell argument to True, this is the process ID of the spawned shell.

http://docs.python.org/library/subprocess.html

This will at least kill the correct process. Not sure if it will close the terminal.

Edit: to kill the process and close the terminal:

p = Popen(['gnome-terminal', '--disable-factory', '-e', path_to_file], preexec_fn=os.setpgrp)

os.killpg(p.pid, signal.SIGINT)

Credit to https://stackoverflow.com/a/34690644/15793575, whih I modified for your command:

  • --disable-factory is used to avoid re-using an active terminal so that we can kill newly created terminal via the subprocess handle
  • os.setpgrp puts gnome-terminal in its own process group so that os.killpg() could be used to send signal to this group
  • This: p = Popen(['gnome-terminal', '--disable-factory', '-e', path_to_file], preexec_fn=os.setpgrp) os.killpg(p.pid, signal.SIGINT) is working for me. But what to do if in child process you have to do something before a closing? For example if you have open files or you have to save your work befor you close a program? – luki May 03 '21 at 12:23
  • HOW TO RUN PYTHON SCRIPT AS SUBPROCESS IN VENV? – luki May 03 '21 at 17:45
  • I found answer in os.environ in child process. If i call parent in env, child is called in env. – luki May 03 '21 at 18:17
0

Popen.pid
The process ID of the child process.

Note that if you set the shell argument to True, this is the process ID of the spawned shell.

Try setting the shell argument of the Popen constructor to False. (p = Popen(['gnome-terminal', "--", path_to_file]) -> p = Popen(['gnome-terminal', "--", path_to_file], shell=False)). I had a similar issue not long ago - this fixed it for me.

TheEagle
  • 5,808
  • 3
  • 11
  • 39
  • Hello. I tested with shell=False, but doesn't help me. When parent program is finished, child is still working. – luki May 03 '21 at 12:03