Si vous êtes sur un système qui utilise logind, alors loginctl
vous indiquera si la session est distante :
$ loginctl show-session $XDG_SESSION_ID -P Remote
yes
Cependant, il y a des cas où XDG_SESSION_ID n'est pas défini (y compris après sudo), donc j'ai écrit un script pour vérifier plus de choses. Il essaie loginctl, ssh, l'affichage X à distance et si tout échoue, se connecte à logind via D-Bus et tente de découvrir la session actuelle en utilisant le PID du processus actuel comme clé :
#!/usr/bin/env python3
from os import environ, getpid, system
from sys import argv, stderr
from dbus import SystemBus
from dbus.exceptions import DBusException
DEBUG=0
LOGIND = ('org.freedesktop.login1', '/org/freedesktop/login1')
MANAGER = '%s.Manager' % LOGIND[0]
SESSION = '%s.Session' % LOGIND[0]
SESSION_NOT_FOUND = '%s.NoSessionForPID' % LOGIND[0]
REMOTE = 'Remote'
LOGINCTL = 'loginctl show-session %s -P %s'
PROPERTIES = 'org.freedesktop.DBus.Properties'
DISPLAY = 'DISPLAY'
SSH='SSH_CLIENT'
def debug(msg):
if DEBUG: print(msg, file=stderr)
def try_loginctl():
debug('Trying loginctl...')
try:
r = system(LOGINCTL % (environ['XDG_SESSION_ID'], REMOTE))
# exit early if loginctl prints the result by itself
if r == 0: raise SystemExit
except KeyError:
pass
return False
def try_ssh():
debug('Trying ssh...')
return bool(environ.get(SSH))
def try_x():
debug('Trying X...')
try:
display = environ[DISPLAY]
return ':' in display and len(display.split(':', 1)[0]) > 0
except KeyError:
return False
def try_dbus():
debug('Trying dbus...')
bus = SystemBus()
logind = bus.get_object(*LOGIND)
try:
pid = getpid()
session_path = logind.GetSessionByPID(pid, dbus_interface=MANAGER)
except DBusException as e:
if e.get_dbus_name() == SESSION_NOT_FOUND:
return False
else:
raise
session = bus.get_object(LOGIND[0], session_path)
remote = session.Get(SESSION, REMOTE, dbus_interface=PROPERTIES)
return bool(remote)
def main():
global DEBUG
if '-d' in argv or '--debug' in argv:
DEBUG=1
remote = try_loginctl() or try_ssh() or try_x() or try_dbus()
print(remote and 'yes' or 'no')
main()