2014-11-21 2 views
-1

У меня есть код ROS rostopic pub toggle_led std_msgs/Empty, который в основном запускается один раз и продолжает работать до тех пор, пока не нажимается CTRL+C.
Теперь я хотел бы автоматизировать эту команду с Python. Я проверил Calling an external command in Python, но он показывает только, как запустить команду.
Как начать и прекратить выполнение этого процесса, когда и когда захочу?Остановить запуск запущен с Python

+1

проверить это: http://stackoverflow.com/questions/4789837/how-to-terminate-a-python-subprocess-launched-with-shell-true – user3885927

+0

Там много способов сделать это в зависимости от деталей из ваших требований (что еще делает скрипт: хотите ли вы запускать многострочный сценарий и demonize rostopic? это gui или командная строка?). Вам действительно нужно опубликовать свой код, если вы хотите что-то большее, чем смутное описание того, что делать. – tdelaney

+0

@tdelaney Я просто хочу, чтобы общее решение работало для любого кода командной строки. Существует несколько подобных команд, которые будут работать до тех пор, пока не будут остановлены вручную. Поэтому, я думаю, код не применим. –

ответ

1

Как мне начать и прекратить выполнение этого процесса, когда и когда захочу?

Ну, вы уже знаете, как это начать, как вы сказали в предыдущем предложении.

Как вы его остановите? Если вы хотите, чтобы остановить его так же, как Ctrl-C, * вы сделаете это, позвонив send_signal на него, используя CTRL_C_EVENT на Windows, или SIGTERM на Unix ** Итак:.

import signal 
import subprocess 

try: 
    sig = signal.CTRL_C_EVENT 
except NameError: 
    sig = signal.SIGTERM 

p = subprocess.Popen(['/path/to/prog', '-opt', '42', 'arg']) 
# ... later 
p.send_signal(sig) 

Если вы только забота о Linux (или * nix вообще), вы можете сделать это еще проще: terminate гарантированно сделает то же самое, что и send_signal(SIGTERM). Итак:

import subprocess 
p = subprocess.Popen(['/path/to/prog', '-opt', '42', 'arg']) 
# ... later 
p.terminate() 

Поскольку вы спросили в комментариях «Не могли бы вы объяснить различные параметры subprocess.Popen()»: Ну, есть много из них (см Popen Constructor и Frequently Used Arguments в документации, но я 'm только с использованием одного параметра args.

Обычно вы передаете список args, с именем программы в качестве первого элемента в списке и каждым отдельным аргументом командной строки в качестве отдельного элемента. если вы хотите использовать оболочку, вы передаете строку для args, и добавьте shell=True в качестве еще одного аргумента.


* Обратите внимание, что «так же, как Ctrl-C» не может быть на самом деле то, что вы хотите на Windows, если программа не имеет консоль и является владельцем группы процесса. Это может означать, что вам необходимо добавить creationflags=subprocess.CREATE_NEW_PROCESS_GROUP в звонок Popen. Или это может не быть, например, если вы используете shell=True.

** В Python, как правило, можно игнорировать различие платформы между CTRL_C_EVENT и SIGTERM и всегда использовать последний, но subprocess.send_signal является одним из немногих мест, где вы не можете. В Windows send_signal(SIGTERM) вызовет terminate вместо отправки Ctrl-C. Если вам действительно неинтересно, как процесс останавливается, просто он каким-то образом остановится, тогда, конечно, вы можете использовать SIGTERM ... но в этом случае вы можете просто позвонить terminate.

+0

Это прекрасно. Спасибо @abarnert –

+0

Не могли бы вы объяснить различные параметры 'subprocess.Popen()'? –

+2

@KanishkaGanguly это список параметров команды, которую вы хотите запустить с помощью подпроцесса, считайте, что вы хотите запустить 'ls -l', что вы сделали бы:' p = subprocess.Popen (["ls", "- l" ]) '. – igon

Смежные вопросы