Note that satella’s posix submodule is a deprecated alias for os

Note that in blatant disregard of this name’s module some of these routines will work on Windows. So, a routine is available on Windows unless stated otherwise.


satella.os.whereis(name: str) → Iterator[str]

Looking in PATH return a sequence of executable files having provided name.

Additionally, on Windows, it will use PATHEXT.


on Windows name is supposed to be without extension!

Parameters:name – name of the executable to search for
Returns:an iterator of absolute paths to given executable


Kill your process (and your process group). Does not work on Windows (NotImplementedError). See issue #37 on GitHub.

satella.os.suicide(kill_entire_pg: bool = True) → None

Kill self.

Parameters:kill_entire_pg – whether to kill entire PG if a session leader. Won’t work on Windows.


Become a daemonized process. Does not work on Windows (OSError).

satella.os.daemonize(exit_via: Callable = <built-in function exit>, redirect_std_to_devnull: bool = True, uid: Optional[int] = None, gid: Optional[int] = None)

Make this process into a daemon.

This entails:

  • umask 0
  • forks twice
  • be the child of init
  • becomes session leader
  • changes root directory to /
  • closes stdin, stdout, stderr
  • (option) redirects stdin, stdout, stderr to /dev/null

Refer - “Advanced Programming in the UNIX Environment” 13.3

  • exit_via – callable used to terminate process
  • redirect_std_to_devnull – whether to redirect stdin, stdout and stderr to /dev/null
  • uid – User to set (via seteuid). Default - this won’t be done. You can pass either user name as string or UID.
  • gid – Same as UID, but for groups. These will be resolved too.
  • KeyError – uid/gid was passed as string, but getpwnam() failed
  • OSError – platform is Windows


Sleep until a signal is received.

satella.os.hang_until_sig(extra_signals: Optional[Sequence[int]] = None, sleep_interval: float = 2) → None

Will hang until this process receives SIGTERM or SIGINT. If you pass extra signal IDs (signal.SIG*) with extra_signals, then also on those signals this call will release.

Periodic sleeping with polling was chosen as the approach of choice, as pause() seemed to work a bit shakily multi-platform.

  • extra_signals – a list of extra signals to listen to
  • sleep_interval – amount of time to sleep between checking for termination condition.


Return if running as root. Routine unavailable on Windows (OSError).

satella.os.is_running_as_root() → bool

Is this process running as root?

Checks whether effective UID is 0

Raises:OSError – called on Windows!


This is meant to acquire a lock on a file.

class satella.os.PIDFileLock(pid_file, base_dir='/var/run')

Acquire a PID lock file.


>>> with PIDFileLock('my_service.pid'):
>>>     ... rest of code ..

Any alternatively

>>> pid_lock = PIDFileLock('my_service.pid')
>>> pid_lock.acquire()
>>> ...
>>> pid_lock.release()

The constructor doesn’t throw, __enter__ or acquire() does, one of:

  • ResourceLocked - lock is already held. This has two attributes - pid (int), the PID of holder,
    and is_alive (bool) - whether the holder is an alive process
acquire() → None

Acquire the PID lock

Raises:ResourceLocked – if lock if held
release() → None

Free the lock :raises RuntimeError: lock not acquired