おかげで、私はこのコードで終わっている:それは、Linux、MacOSの、およびWindows上で動作します
import platform
import re
import subprocess
from typing import Set
if platform.system() == 'Windows':
def _get_ports(pid):
sp = subprocess.run(['netstat', '-anop', 'TCP'],
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
check=True)
rx_socket = re.compile(br'''(?x)^
\s* TCP
\s+ 127.0.0.1 : (?P<port>\d{1,5})
\s+ .*?
\s+ LISTENING
\s+ (?P<pid>\d+)
\s* $''')
for line in sp.stdout.splitlines():
rxm = rx_socket.match(line)
if rxm is None:
continue
sock_port, sock_pid = map(int, rxm.groups())
if sock_pid == pid:
yield sock_port
else:
def _get_ports(pid):
sp = subprocess.run(['lsof', '-anlPFn', '+w',
f'-p{pid}', '[email protected]', '-sTCP:LISTEN'],
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
check=True)
for line in sp.stdout.splitlines():
if line.startswith(b'n'):
host, port = line.rsplit(b':', 1)
port = int(port)
yield port
def get_ports(pid: int) -> Set[int]:
"""Get set of local-bound listening TCPv4 ports for given process.
:param pid: process ID to inspect
:returns: set of ports
"""
return set(_get_ports(pid))
print(get_ports(12345))
、及びある特定のプロセスのためのすべてのローカルに結合TCPv4ポートを発見しますLISTEN状態である。また、すべての種類のホスト/ポート/ユーザー名の逆引き検索をスキップして高速化し、昇格された特権を必要としません。
最後に、0.0.0.0:0
でAppium(または他のもの)を起動させるという考えは、OSが提供する最初の利用可能なポートにバインドして、現在リッスンしているポートを調べます。競争条件はありません。
ランダムなポートを選択してAppiumに渡し、正しいエラーメッセージがないかどうかを確認することができます。 –
あなたは任意のポートを試すことができませんし、 'EADDRINUSE'を返すとそれを増やし、空きが見つかるまでループしますか? – rodrigo
@AlexHall、これは私が今やっていることです。しかし、問題は「正しい方法」についてです。サブプロセスのポート番号を予約する方法はありますか? – toriningen