Running processes

pshell.find_procs_by_cmdline(*cmdlines: str | Path) list[Process]

Search all processes that have a partial match for at least one of the given command lines. Command lines are parsed through resolve_env().

For example, the command:

find_procs_by_cmdline('$MYROOT')

will return a match for the following processes:

  • $MYROOT/static/scripts/something.sh

  • tail -f $LOGDIR/mylog.log

  • myservice.sh -c /algodata/someuser/root/cfg/myservice.cfg

where:

  • MYROOT=/algodata/someuser/root

  • LOGDIR=/algodata/someuser/root/log

This method will only return processes for the current user.

Warning

Invoking this with relative paths can give erroneous results. For example, invoking it with ‘foo’ will match, for example, ‘foo.pl’, ‘find_foos.sh’, and ‘vim foobar.cfg’.

Warning

This command can’t match commands invoked with a relative path if the search parameter is an absolute path. e.g. find_procs_by_cmdline('$MYROOT') won’t be able to match cd $MYROOT/bin && ./myscript.

Parameters:

cmdlines – one or more paths command lines to search for

Returns:

list of psutil.Process objects

pshell.kill(*procs: int | Process | None, term_timeout: float = 10) None

Send SIGTERM to one or more processes. After term_timeout seconds, send SIGKILL to the surviving processes.

This function will return before term_timeout if all processes close themselves following SIGTERM.

This function graciously skips processes that do not exist or for which the user doesn’t have enough permissions. It also automatically skips the current process and its parents.

Parameters:
  • procs – one or more PIDs (int) or psutil.Process objects, e.g. as returned by find_procs_by_cmdline().

  • term_timeout (float) – seconds to wait between SIGTERM and SIGKILL. If term_timeout==0, immediately send SIGKILL.

pshell.killall(*cmdlines: str | Path, term_timeout: float = 10) None

Find all processes with the target command line(s), send SIGTERM, and then send SIGKILL to the survivors.

See find_procs_by_cmdline() and kill().

pshell.wait_for_server(proc: int | Process, port: int | None = None, *, ignore_ports: Collection[int] | None = None, timeout: float | None = None) int

Wait until either the process starts listening on the given port, or it crashes because the port is occupied by something else.

Parameters:
  • proc – psutil.Process or Process ID to observe

  • port (int) – Port that needs to be opened in listening mode. If omitted, return when any one port is opened.

  • ignore_ports – List or set of ports to ignore (only meaningful when port is None).

  • timeout (int) – Number of seconds to wait before giving up; omit for no timeout

Returns:

Opened port number

Raises:

Example:

import subprocess
import pshell

proc = subprocess.Popen(["redis-server"])
port = pshell.wait_for_server(proc.pid)
assert port == 6379

This can also be used to start a server on port 0, which makes it atomically pick up a random free port, and then retrieve said port.