Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 24/02/2023, à 22:56

lynn

[ Script bash ] Verrouiller son écran en utilisant le bluetooth

Bonjour,

Je me suis écris un petit script shell qui va verrouiller l'écran du pc si la connexion bluetooth entre ce dernier et le smartphone se coupe et ce, au bout d'un temps préalablement défini. L'idée n'est pas nouvelle mais à part cette extension pour Gnome Shell, il n y a pas grand chose... et encore, cette extension fonctionne bien avec Ubuntu 22.04 mais pas avec la version actuelle de développement (23.04).

Et puis enfin, tout le monde n'utilise pas Gnome comme environnement alors avec un script, c'est pratique.

Complément : Ajout d'une méthode, à la fin de ce post, pour lancer le script ci-dessous au démarrage du pc, en utilisant systemd.

J'ai mis des commentaires partout (surtout pour m'y retrouver). N'hésitez pas à me hurler dessus à me dire gentiment si il y a des points à corriger/améliorer... et il y en a tant mon niveau de scripting est bas. tongue

#!/bin/bash

##
# SmartLock Screen, par lynn
# Avec les conseils éclairés 
# de Watael :)
#
# Verrouille l'écran du pc en utilisant
# l'état de la connexion bluetooth entre
# votre smartphone et votre PC.
# 
# L'adresse MAC et le nom de l'appareil 
# peuvent être obtenus avec la commande 
# 'bluetoothctl devices'
# 
# Dernière révision le 09/06/2023
# Version 0.3
# Licence : libre, très libre..! 
##

# Informations à remplir par l'utilisateur
# N.B : La valeur 'time2lock' est exprimée en secondes
mac="XX:XX:XX:XX:XX:XX"
deviceName="Nom du smartphone"
time2lock="Valeur en secondes"

# Ne rien modifier en dessous de cette ligne
TZ=UTC printf -v notifyTime '%(%H heure(s) %M minute(s) %S seconde(s))T' $time2lock
notify="notify-send -i phone --hint=int:transient:1"
scrLockOut=false
switchTTY=false

isScreenLocked() {
    local XDG_SESSION_ID=$(loginctl user-status | awk '/^[[:space:]]+Sessions/{for(i=1;i<=NF;i++){if(index($i,"*")==1){ sub(/^\*/,"",$i);print $i;}}}')
    readarray -t properties < <(loginctl show-session $XDG_SESSION_ID --value -p Type -p State -p LockedHint)
    read type state locked < <(printf '%s ' "${properties[@]}") 
    [[ $type == @(x11|wayland) && $state == active && $locked == yes ]]
}

isGUI() {
    local XDG_SESSION_ID=$(loginctl user-status | awk '/^[[:space:]]+Sessions/{for(i=1;i<=NF;i++){if(index($i,"*")==1){ sub(/^\*/,"",$i);print $i;}}}')
    case $1 in
    onTTY) loginctl show-session $XDG_SESSION_ID | grep -qw "State=online"
    ;;
    *) exit 1
    ;;
    esac
}

isPCbt() {
    case $1 in
    PlaneMode) rfkill list | grep -qow "Soft blocked: yes"
    ;;
    Powered) bluetoothctl show | grep -qw "Powered: yes"
    ;;
    *) exit 1
    ;;
    esac
}

isPhone() {
    case $1 in
    Paired|Connected|Trusted) bluetoothctl info $mac | grep -qw "${1^}: yes"
    ;;
    *) exit 1
    ;;
    esac
}

btConnect() {
# Vérifications mode avion [yes/no], bluetooth [on/off], apppairage [yes/no], appareil de confiance [yes/no]
# et appareils connectés [yes/no].
# Au démarrage du pc, le script attendra que le réseau bluetooth du smartphone soit 
# détecté et la connexion établie avant de poursuivre
while :
do
    if isPCbt PlaneMode; 
    then
        rfkill unblock bluetooth
    elif ! isPCbt Powered
    then
        bluetoothctl power on
    elif ! isPhone Paired
    then
        bluetoothctl pair $mac
    elif ! isPhone Trusted
    then
        bluetoothctl trust $mac
    elif ! isPhone Connected
    then
        bluetoothctl --timeout 10 connect $mac
    elif isPhone Connected
    then
        break
    else
        sleep 1
    fi
done
}
btConnect

# Gestion du verrouillage de l'écran et de reconnexion du bluetooth
while :
do
    # 'timeLeft' correspond au temps avant verrouillage, défini en début de script par l'utilisateur dans la variable 'time2lock'
    timeLeft=$time2lock
    # 'canNotify=true' permet à une notification de s'afficher visuellement
    canNotify=true
    sleep 1
    # Si l'écran est verrouillé, que le smartphone est à proximité avec son bluetooth actif et qu'il 
    # ne se reconnecte pas automatiquement, on force la reconnexion
    if [ "$scrLockOut" = "true" ]
    then
        btConnect
        scrLockOut=false
    # Le bluetooth peut se couper lors d'un passage sur 'TTY' (constaté sur Ubuntu > 22.04) ou d'une fermeture de session
    # La connexion sera alors rétablie au retour en session graphique
    elif [ "$switchTTY" = "true" ]
    then
        btConnect
        switchTTY=false
    fi
    # Tant que le smartphone n'est pas connecté
    while ! isPhone Connected
    do
        sleep 1
        # 'timeLeft--' est égal à 'timeLeft' moins une seconde
		((timeLeft--))
        # Si la session active n'est pas la session graphique ou bien sur un retour en session graphique
        if isGUI onTTY -o -z "$XDG_SESSION_ID"
        then
            # 'switchTTY=true' indique un passage sur un autre 'TTY' ou une fermeture de session graphique
            # N.B : Il n'y aura pas de bulle de notification dans ces deux cas
            switchTTY=true
            break
        # Bulle de notification affichée au début du compte à rebours
        elif [ "$canNotify" = "true" ]
        then
            $notify "Le smartphone $deviceName n'est pas connecté" "L'écran sera verrouillé dans :\n$notifyTime"
            canNotify=false
        # Si l'écran est verrouillé manuellement pendant le compte à rebours, on sort de la boucle
        elif isScreenLocked
        then
            # 'scrLockOut=true' indique un passage en mode 'écran verrouillé'
            scrLockOut=true
            break
        # Si le smartphone est reconnecté pendant le compte à rebours, on sort de la boucle + notification 
        elif isPhone Connected
        then
            $notify "Le smartphone $deviceName est reconnecté" "Le verrouillage de l'écran est annulé"
            break
        # Si le compte à rebours est terminé et le smartphone non connecté, verrouuillage de l'écran
        elif ((timeLeft==0))
        then
            loginctl lock-session
            # 'scrLockOut=true' indique un passage en mode 'écran verrouillé'
            scrLockOut=true
            break
        fi
    done
done

Créer un service systemd pour lancer le script au démarrage du pc

[1] Créer le service en question

systemctl --user edit --full --force smartlock-screen.service

[2] Dans la fenêtre qui s'ouvre, copier/coller ce qui suit

[Unit]
Description=Verrouillage de l'écran sur déconnexion d'un périphérique bluetooth

[Service]
Type=simple
ExecStart=/home/%u/bin/smartlock-screen.sh

[Install]
WantedBy=graphical-session.target

Enregistrer les modifications

N.B : la partie suivante indique le chemin à prendre pour exécuter le script. %u représente le nom de l'utilisateur. La suite est à modifier en conséquence.

ExecStart=/home/%u/bin/smartlock-screen.sh

[3] Activer le service

systemctl --user enable smartlock-screen.service

Dernière modification par lynn (Le 09/06/2023, à 19:13)


«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#2 Le 24/02/2023, à 23:16

Watael

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

salut,

attention, les variables définies dans une fonction sont globales, à moins qu'elles soient explicitement définies en tan que local.

tout le monde n'utilise pas Gnome comme environnement alors avec un script, c'est pratique.

mais pas un script qui utilise gnome-screensaver !


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#3 Le 25/02/2023, à 00:17

kamaris

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

Puisque tu utilises bash, n'hésite pas à utiliser l'évaluation arithmétique ((…)) qui rend en général le code plus lisible.
Par exemple

((iterations++))
while ((iterations >= max_iterations)); do

au lieu de

iterations=$((iterations+1))
while [ $iterations -ge $max_iterations ]; do

D'ailleurs ça ne serait pas plutôt <= ou -le ?

Dernière modification par kamaris (Le 25/02/2023, à 00:20)

Hors ligne

#4 Le 25/02/2023, à 00:18

lynn

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

Pour les variables dans une fonction, à part $mac, je n'en vois pas d'autres...

Alors pour gnome-screensaver, je veux bien des commandes qui font la même la même chose mais qui fonctionnent... j'ai essayé ça

dbus-send --type=method_call \
    --dest=org.gnome.ScreenSaver /org/gnome/ScreenSaver \
    org.freedesktop.DBus.Properties.Get \
    string:"org.gnome.ScreenSaver" \
    string:"Active"

et

gdbus call -e -d org.gnome.ScreenSaver -o /org/gnome/ScreenSaver \
    -m org.freedesktop.DBus.Properties.Get \
    org.gnome.ScreenSaver Active

mais rien ne fonctionne... Donc si tu as quelque chose sous la main, ça m'intéresse. smile


«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#5 Le 25/02/2023, à 00:21

lynn

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

Bonjour kamaris,

Merci pour ta remarque, J'en prends bonne note et modifierai en conséquence.


«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#6 Le 25/02/2023, à 00:27

lynn

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

Pour les variables, en fait il y en a deux effectivement...  en fait j'ai ajouté LANG=C après tout le reste.
Effectivement, il vaut peut-être mieux garder cette variable en local.


«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#7 Le 25/02/2023, à 01:56

lynn

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

Deuxième mouture du script (dans mon premier message). J'ai retiré la commande

gnome-screensaver

J'ai réussi à trouver les commandes gdbus qui vont bien pour déterminer l'état du verrouillage de l'écran et pour lancer le verrouillage.
Ça progresse...


«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#8 Le 25/02/2023, à 03:31

Watael

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

puisque gdbus s'adresse à org.gnome.ScreenSaver, le script ne sera toujours utilisable que par les utilisateurs de Gnome.

je ne sais pas si il existe une sorte de panacée qui permettrait de contrôler la mise en veille de tous les environnements... une fonction freeDesktop, peut-être ?
sinon, il va falloir adapter après avoir déterminé l'environnement en cours de l'utilisateur du script.

PS: c'est la véritable adresse MAC de ton téléphone ?

Dernière modification par Watael (Le 25/02/2023, à 03:40)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#9 Le 25/02/2023, à 03:59

lynn

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

Merci Watael, j'ai modifié l'adresse MAC dans le script. Bien que je sache pas si ça à vraiment une incidence concernant la sécurité vu que ce numéro est visible lors du scan des appareils... mais bon, dans le doute j'ai modifié. tongue

Pour gdbus, je suis bien d'accord. Une fonction à la freeDesktop serait bien si ça existe... Est-ce que chaque environnement ne brode un truc à sa sauce..!? Je vais me renseigner.


«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#10 Le 25/02/2023, à 07:06

lynn

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

Petit changement pour verrouiller la session, on passe désormais par

loginctl lock-session

Pour avoir le statut du verrouillage, je n'est toujours pas trouvé... J'ai tenté ça

gdbus call --session --dest org.freedesktop.ScreenSaver  --object-path /org/freedesktop/ScreenSaver --method org.freedesktop.ScreenSaver.GetActive

mais ça me répond

Erreur : GDBus.Error:org.freedesktop.DBus.Error.NotSupported: This method is not implemented

«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#11 Le 25/02/2023, à 08:43

k3c

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

joli !

il me semble avoir vu un article sur ce sujet dans Linux Mag ou Linux Pratique

blueproximity ?

https://doc.ubuntu-fr.org/blueproximity

ou bluetooth-unlock

https://github.com/LethalEthan/Bluetooth-Unlock


Archlinux sur Xiaomi Air 13

Hors ligne

#12 Le 25/02/2023, à 11:12

kamaris

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

lynn a écrit :

Pour gdbus, je suis bien d'accord. Une fonction à la freeDesktop serait bien si ça existe... Est-ce que chaque environnement ne brode un truc à sa sauce..!? Je vais me renseigner.

Malheureusement la spec dit peu de choses (je crois que c'est la seule) : https://specifications.freedesktop.org/ … /re01.html
Divers environnement implémentent cependant org.freedesktop.ScreenSaver.Lock (non spécifiée), mais rien de sûr.
Donc chacun y va de son switch-case au final et/ou ne se soucie plus ou moins que de son propre screensaver.

Hors ligne

#13 Le 25/02/2023, à 14:55

lynn

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

@k3c, bonjour et merci pour les infos
J'avais vu pour blueproximity mais c'est plus trop suivi... pour bluetooth-unlock, j'avais zappé. Je vais étudier ça.

Sinon, j'ai trouvé ça et franchement, si il faut gratter dans tout ça pour déterminer quelle commande va fonctionner en fonction de tel ou tel environnement... bah c'est pas glop ! Ma fonction isScreenLocked à elle seule ferait au moins quatre fois la longueur du script...
Il y a bien, quelque part, un fichier qui change quand l'écran est verrouillé et qui reprend une autre valeur quand c'est déverrouillé..!? Un truc commun à plusieurs environnements; sinon, quel est l'intérêt de mettre en place une norme si tout le monde fait à sa sauce ?


«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#14 Le 25/02/2023, à 15:09

Watael

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

un fichier ? probablement. mais pas forcément le même selon l'environnement. tongue lol


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#15 Le 25/02/2023, à 17:25

k3c

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

j'ai retrouvé l'article, qui est payant

https://connect.ed-diamond.com/Linux-Pr … smartphone

je vais regarder si j'ai ce numéro dans mes archives


Archlinux sur Xiaomi Air 13

Hors ligne

#16 Le 25/02/2023, à 18:51

lynn

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

J'ai réalisé un ajustement du code pour stopper le spam des bulles de notification quand l'écran est verrouillé.


«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#17 Le 25/02/2023, à 22:19

lynn

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

Éclaircissement du code et correction de quelques erreurs.


«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#18 Le 25/02/2023, à 22:44

Watael

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

d'un point de vue "mise en page", je n'aime pas avoir les commentaires après les commandes, et sur la même ligne.
quand je fais un script, je rédige une sorte d'algorithme (je prévois les opérations), et ensuite je code.
ça me permet aussi de ne pas avoir des lignes à rallonge.

isScreenLocked() {
    local locked #<là, je le fais parce que je commente un script a posteriori. :)
    locked=$(gdbus call --session --dest "$ogSS" --object-path "/${ogSS//./\/}" --method "$ogSS.GetActive" 2> /dev/null) #<la commande peut tenir sur une ligne.
    test "$locked" = "(true,)"
}

avec ogSS définie précédemment ainsi :

ogSS='org.gnome.ScreenSaver'

Dernière modification par Watael (Le 25/02/2023, à 22:45)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#19 Le 25/02/2023, à 23:14

Watael

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

$ TZ=UTC printf -v notify_time '%(%H heure(s) %M minute(s) %S seconde(s))T' $time_to_lock
$ echo $notify_time
00 heure(s) 05 minute(s) 00 seconde(s)
$

Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#20 Le 25/02/2023, à 23:21

lynn

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

Pour les commentaires, c'est surtout pour moi... On peut les enlever si on veut. Pour les fonctions, je ne trouve pas ça très gênant de couper la ligne. Mis comme ça, je trouve même que ça simplifie la compréhension de ce qu'on écrit. Enfin bon, ce n'est que mon avis.

Par contre, dans la variable ci dessous, il y aurait un moyen de couper la ligne ou c'est réservé aux fonctions ?

notify_time=$(printf '%02d heure(s) %02d minute(s) %02d seconde(s)\n' $((time_to_lock/3600)) $((time_to_lock%3600/60)) $((time_to_lock%60)))

«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#21 Le 25/02/2023, à 23:21

lynn

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

J'ai ma réponse.... tongue


«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#22 Le 25/02/2023, à 23:23

Watael

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

non, ne les enlève pas. il est recommandé d'en avoir : nous aussi on doit pouvoir s'y référer.

Dernière modification par Watael (Le 25/02/2023, à 23:24)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#23 Le 25/02/2023, à 23:49

lynn

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

Petite question au passage, y aurait-il un moyen propre de faire défiler dans la bulle de notification, le temps qui décompte, sans pour autant créer du spam en affichant une nouvelle bulle à chaque fois ?


«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#24 Le 26/02/2023, à 05:12

lynn

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

Pour le verrouillage de l'écran et statuer sur l'état de ce dernier, le script utilise maintenant loginctl à la place de gdbus. Reste à savoir si cette commande est présente de base sur les autres environnements...


«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#25 Le 26/02/2023, à 14:23

Watael

Re : [ Script bash ] Verrouiller son écran en utilisant le bluetooth

freedesktop.org a écrit :

loginctl may be used to introspect and control the state of the systemd(1) login manager[...]


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne