Вы можете удалить незаконные символы с помощью Linq следующим образом:
var invalidChars = Path.GetInvalidFileNameChars (); var invalidCharsRemoved = stringWithInvalidChars .Where (x = & gt;! invalidChars.Contains (x)) .ToArray ();
EDIT Вот как он выглядит с требуемым правлением, упомянутым в комментариях:
var invalidChars = Path.GetInvalidFileNameChars (); string invalidCharsRemoved = новая строка (stringWithInvalidChars .Where (x = & gt;! invalidChars.Contains (x)) .ToArray ());
Используйте группу процессов , чтобы включить отправку сигнала ко всему процессу в группах. Для этого вы должны прикрепить session id к родительскому процессу процессов порожденного / дочернего процесса, который является оболочкой в вашем случае. Это сделает его лидером группы процессов. Итак, теперь, когда сигнал отправляется руководителю группы процессов, он передается всем дочерним процессам этой группы.
Вот код:
import os
import signal
import subprocess
# The os.setsid() is passed in the argument preexec_fn so
# it's run after the fork() and before exec() to run the shell.
pro = subprocess.Popen(cmd, stdout=subprocess.PIPE,
shell=True, preexec_fn=os.setsid)
os.killpg(os.getpgid(pro.pid), signal.SIGTERM) # Send the signal to all the process groups
Ни один из этих ответов не работал для меня, поэтому я оставил код, который действительно работал. В моем случае даже после убийства процесса с помощью .kill()
и получения кода возврата .poll()
процесс не завершился.
Следуя документации subprocess.Popen
:
"... для правильной очистки хорошо выполненное приложение должно убить дочерний процесс и завершить связь ... »
proc = subprocess.Popen(...) try: outs, errs = proc.communicate(timeout=15) except TimeoutExpired: proc.kill() outs, errs = proc.communicate()
В моем случае я не получил
proc.communicate()
после вызоваproc.kill()
. Это очищает процесс stdin, stdout ... и завершает процесс.
Я мог бы сделать это с помощью
from subprocess import Popen
process = Popen(command, shell=True)
Popen("TASKKILL /F /PID {pid} /T".format(pid=process.pid))
, он убил cmd.exe
и программу, для которой я дал команду.
(В Windows)
Как сказал Саи, оболочка - это ребенок, поэтому сигналы перехватываются им - лучший способ, который я нашел, - использовать shell = False и использовать shlex для разделения командной строки:
if isinstance(command, unicode):
cmd = command.encode('utf8')
args = shlex.split(cmd)
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
Затем p.kill () и p.terminate () должны работать так, как вы ожидаете.
cwd
в Popen
.
– Jonathon Reinhart
17 August 2015 в 01:22
Если вы можете использовать psutil , то это отлично работает:
import subprocess
import psutil
def kill(proc_pid):
process = psutil.Process(proc_pid)
for proc in process.children(recursive=True):
proc.kill()
process.kill()
proc = subprocess.Popen(["infinite_app", "param"], shell=True)
try:
proc.wait(timeout=3)
except subprocess.TimeoutExpired:
kill(proc.pid)
AttributeError: 'Process' object has no attribute 'get_children
для pip install psutil
.
– d33tah
13 July 2015 в 21:47
Когда shell=True
оболочка является дочерним процессом, а командами являются ее дочерние элементы. Таким образом, любые SIGTERM
или SIGKILL
будут убивать оболочку, но не ее дочерние процессы, и я не помню хороший способ сделать это. Лучший способ, который я могу придумать, - использовать shell=False
, иначе, если вы убьете процесс родительской оболочки, он оставит процесс с отсутствующей оболочкой.
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
p.kill()
p.kill()
завершает работу с оболочкой и cmd
все еще работает.
Я нашел удобное исправление:
p = subprocess.Popen("exec " + cmd, stdout=subprocess.PIPE, shell=True)
Это будет заставить cmd наследовать процесс оболочки, вместо того чтобы заставить оболочку запускать дочерний процесс, который не убивается. p.pid
будет идентификатором вашего процесса cmd.
p.kill()
должен работать.
Я не знаю, какое влияние это будет на вашу трубу.
preexec_fn=os.setpgrp
также работает – Zang MingJie 29 August 2012 в 10:52subprocess.CREATE_NEW_PROCESS_GROUP
относится к этому? – Piotr Dobrogost 19 October 2012 в 11:53CREATE_NEW_PROCESS_GROUP
может использоваться для эмуляцииstart_new_session=True
в Windows – jfs 4 December 2013 в 00:04