Я написал небольшой интерфейс на Python, который позволяет пользователям воспроизводить интернет-радиоканалы. Программа использует Pythons subprocess () для инициализации mplayer для настройки на канал, например:
runn = "mplayer http://77.111.88.131:8010"
p = subprocess.Popen(runn, shell=True)
pid = int(p.pid)
wait = os.waitpid(p.pid, 1)
Затем сохраняет p.pid, и когда пользователь хочет прекратить прослушивание, используется следующий код:
os.kill(p.pid, 9)
Это прекрасно работает в OpenSUSE, но не в Ubuntu. Кажется, что Ubuntu фактически запускает два отдельных процесса. Терминальный выход:
Opensuse 11.3:
$ pgrep mplayer
22845
Ubuntu 10.04:
$ pgrep mplayer
22846
22847
Это также применяется при запуске других программ. Кто-нибудь знает почему? Я действительно хочу, чтобы это приложение работало на всех дистрибутивах, поэтому любая помощь очень ценится.
3 ответа
Попробуй это:
p = subprocess.Popen(runn.split(), shell=False)
Я думаю, что происходит, это ...
Когда вы говорите, что shell=True
подпроцесс фактически запускает эту команду sh -c "your string"
. Команда sh
затем интерпретирует вашу строку и запускает команду, как будто вы ввели ее в командной строке (более или менее). Обычно это приводит к двум процессам. Один будет sh -c "your string"
, а другой - дочерний, your string
.
Некоторые версии sh
имеют оптимизацию, в которой они автоматически exec
выполняют команду при определенных условиях. Они делают это, если это последняя команда, которую sh
собирается выполнить, и у sh
нет другой причины остаться. При использовании sh -c
для запуска команды это почти всегда приводит к тому, что вызов sh
заменяет себя выполняемой командой, в результате чего получается один процесс.
На мой взгляд, это действительно очень плохая идея - вызывать subprocess.Popen
с shell=True
. Делая это, вы открываете себе массу проблем безопасности и, как правило, менее предсказуемого поведения, поскольку метасимволы оболочки интерпретируются sh -c
.
subprocess.Popen возвращает объект Popen с несколько полезных методов. Вероятно, это плохая идея, чтобы прекратить вещи, используя непосредственно os.kill ...
Происходит ли то же самое, если вы используете объект Popen p.terminate () или p.kill ()?
У меня нет точного ответа, но вот несколько способов выяснить это:
Используйте pstree
, чтобы проверить отношения родитель / потомок между процессами.
Используйте ps -awux
для просмотра полных аргументов командной строки для всех процессов.
Обратите внимание, что использование shell=True
запускает процесс оболочки (например, /bin/bash
), который запускает mplayer
. Это может быть еще один путь для расследования. Обе системы используют одну и ту же оболочку?
Обе системы используют одну и ту же версию mplayer? питона?
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.