เรียกใช้สคริปต์บนล็อคหน้าจอ / ปลดล็อค


54

ฉันต้องการเรียกใช้หน้าจอหากเซสชัน Gnome ถูกล็อกและปลดล็อค มีวิธีที่ฉันสามารถดักจับสิ่งนี้และดำเนินการบางอย่างเมื่อเดสก์ท็อปถูกล็อกหรือปลดล็อกหรือไม่?

คำตอบ:


49

Gnome-screensaver ส่งสัญญาณบางอย่างไปยัง dbus เมื่อมีบางอย่างเกิดขึ้น

นี่คือเอกสารประกอบ (พร้อมตัวอย่าง)

คุณสามารถเขียนสคริปต์ที่ทำงาน:

dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'"

และทำสิ่งที่คุณต้องการได้ตลอดเวลาdbus-monitorพิมพ์บรรทัดเกี่ยวกับหน้าจอที่ถูกล็อค / ปลดล็อค


นี่คือคำสั่ง bash ที่จะทำสิ่งที่คุณต้องการ:

dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'" |
  while read x; do
    case "$x" in 
      *"boolean true"*) echo SCREEN_LOCKED;;
      *"boolean false"*) echo SCREEN_UNLOCKED;;  
    esac
  done

เพียงแค่เปลี่ยนecho SCREEN_LOCKEDและecho SCREEN_UNLOCKEDมีสิ่งที่คุณต้องการ


สวัสดี @peoro นั่นทำให้ฉันคิดว่าคุณสามารถปลดล็อคหรือล็อคหน้าจอคำพังเพย / ครั้งจากโปรแกรมสคริปต์มูลค่าการทำเทคนิค SSH บางอย่างเกี่ยวกับมัน ;-)
Nikhil Mulley

1
@Nikhil: การทำเช่นนั้นคุณไม่จำเป็นต้องเล่นกับ dbus: gnome-screensaver-commandมีอยู่แล้ว ผ่าน-aไปคุณจะล็อคหน้าจอในขณะที่คุณจะปลดล็อคด้วยgnome-screensaver-command -dอย่างไรก็ตามแอปคำพังเพยส่วนใหญ่ใช้ dbus อย่างกว้างขวางดังนั้นคุณจะสามารถทำสิ่งที่น่าอัศจรรย์มากมายได้
peoro

1
@peoro ขอบคุณมากมีประโยชน์มาก! ฉันสามารถใช้สิ่งนี้เป็น daemon ได้ไหม เมื่อฉันป้อนสิ่งนี้ในเทอร์มินัลตอนนี้จะต้องเปิดอยู่เพื่อตรวจสอบ dbus สำหรับกรณีนั้น ฉันต้องการที่จะใช้คำสั่งนี้เมื่อเข้าสู่ระบบแล้วมันสามารถใช้งานได้ในช่วงเซสชั่นทั้งหมด
Sander

1
ฉันคิดว่าสิ่งต่าง ๆ อาจมีการเปลี่ยนแปลงในปี 2014? เนื่องจากการแสดงผลไม่เปลี่ยนแปลงหากหน้าจอถูกล็อคมันจะแสดงเฉพาะบางอย่างเมื่อมันถูกทำให้ว่างเปล่าและแตกต่างจากที่นี่มาก :( ฉันสร้างคำถามนี้askubuntu.com/questions/505681/ …คุณเชื่อว่ายังมีบางอย่างอยู่หรือไม่ วิธีที่จะทำอย่างไรขอบคุณ!
อำนาจกุมภ์

วิธีการเรียกใช้สคริปต์ที่มันจับเหตุการณ์ล็อค? ค่อนข้างเหมือนนักดู
Starx

20

ใน Ubuntu 14.04 เหตุการณ์ DBus สำหรับการล็อกการล็อกหน้าจอมีการเปลี่ยนแปลงและสคริปต์ใหม่สำหรับการเชื่อมโยงกับการล็อกหน้าจอและการปลดล็อกเหตุการณ์มีลักษณะดังต่อไปนี้

dbus-monitor --session "type='signal',interface='com.ubuntu.Upstart0_6'" | \
(
  while true; do
    read X
    if echo $X | grep "desktop-lock" &> /dev/null; then
      SCREEN_LOCKED;
    elif echo $X | grep "desktop-unlock" &> /dev/null; then
      SCREEN_UNLOCKED;
    fi
  done
)

แนวคิดเกี่ยวกับวิธีทำให้งานนี้บน fedora 23
Ray Foss

2
ทำงานได้ดีในวันที่ 16.04 เช่นกัน
Jacob Vlijm

@JacobVlijm ขอบคุณสำหรับการทดสอบนี้และไฟเขียวให้ฉันใช้คืนนี้ :)
WinEunuuchs2Unix

6

ทุกวันนี้ฉันคิดว่ามันเป็นการดีที่จะฟังLockedHintมากกว่าข้อความสกรีนเซฟเวอร์ ด้วยวิธีนี้คุณไม่ได้ผูกติดอยู่กับการใช้งานสกรีนเซฟเวอร์

นี่เป็นสคริปต์ง่ายๆที่จะทำ:

gdbus monitor -y -d org.freedesktop.login1 | grep LockedHint

ให้สิ่งนี้:

/org/freedesktop/login1/session/_32: org.freedesktop.DBus.Properties.PropertiesChanged ('org.freedesktop.login1.Session', {'LockedHint': <true>}, @as [])
/org/freedesktop/login1/session/_32: org.freedesktop.DBus.Properties.PropertiesChanged ('org.freedesktop.login1.Session', {'LockedHint': <false>}, @as [])

5

Ubuntu 16.04: โซลูชันของ ozma ไม่ได้ผลสำหรับฉัน แต่อันนี้ทำ:

dbus-monitor --session "type=signal,interface=com.canonical.Unity.Session,member=Unlocked" | 
  while read MSG; do
    LOCK_STAT=`echo $MSG | awk '{print $NF}'`
    if [[ "$LOCK_STAT" == "member=Unlocked" ]]; then
        echo "was unlocked"
    fi
  done

มันอาจใช้ได้กับ Unity แต่มีคำถามเกี่ยวกับ Gnome
cprn

5

การขยายคำตอบที่ได้รับแล้ว

ถ้าคุณพยายามที่จะเรียกใช้สคริปต์จากภายในได้screenหรือtmuxเซสชั่นที่คุณจะต้องไปหาที่ถูกต้อง$DBUS_SESSION_BUS_ADDRESSครั้งแรกและผ่านมันเป็นอาร์กิวเมนต์สำหรับแทนdbus-monitor --sessionนอกจากนี้ถ้าคุณใช้มันเป็น daemon คุณควรตรวจสอบให้แน่ใจเพียงหนึ่งตัวอย่างทำงานที่เวลา (เช่นกับแฟ้มล็อค) trapและว่าสคริปต์ทำความสะอาดขึ้นหลังจากที่ตัวเองด้วย ตัวอย่างต่อไปนี้จะทำงานเป็น daemon ในสภาพแวดล้อม Gnome ล่าสุด (ทดสอบบน Ubuntu GNOME 16.04):

#!/bin/bash
set -o nounset                # good practice, exit if unset variable used

pidfile=/tmp/lastauth.pid     # lock file path
logfile=/tmp/lastauth.log     # log file path

cleanup() {                   # when cleaning up:
    rm -f $pidfile            # * remove the lock file
    trap - INT TERM EXIT      # * reset kernel signal catching
    exit                      # * stop the daemon
}

log() {                       # simple logging format example
    echo $(date +%Y-%m-%d\ %X) -- $USER -- "$@" >> $logfile
}

if [ -e "$pidfile" ]; then    # if lock file exists, exit
    log $0 already running...
    exit
fi

trap cleanup INT TERM EXIT    # call cleanup() if e.g. killed

log daemon started...

echo $$ > $pidfile            # create lock file with own PID inside

# usually `dbus-daemon` address can be guessed (`-s` returns 1st PID found)
export $(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pidof -s dbus-daemon)/environ)

expr='type=signal,interface=org.gnome.ScreenSaver' # DBus watch expression here

dbus-monitor --address $DBUS_SESSION_BUS_ADDRESS "$expr" | \ 
    while read line; do
        case "$line" in
            *"boolean true"*) log session locked;;
            *"boolean false"*) log session unlocked;;
        esac
    done

cleanup # let's not leave orphaned lock file when the loop ends (e.g. dbus dies)

หากสิ่งนี้ไม่ได้ผลสำหรับคุณอาจเป็นเพราะ:

  1. คุณไม่ได้ใช้ Gnome - ตรวจสอบคำตอบอื่น ๆ เพื่อดูการแสดงออกของนาฬิกา DBus ที่ดีขึ้น
  2. คุณเรียกใช้หลาย DBus บรรทัด - ตรวจสอบรายละเอียดเกี่ยวกับวิธีการทำให้ PID ค้นหา deterministic

1
นี้ที่จริงคำตอบคำถามที่แตกต่างผมมีสำหรับการค้นพบข้อมูลแบบไดนามิกเซสชั่น DBus รับบัญชีผู้ใช้ซึ่งผมได้แก้ที่นี่ ขอบคุณสำหรับการสนับสนุนของคุณที่นี่!
Naftuli Kay

ขอบคุณ ฉันจะเชื่อมโยงโซลูชันของคุณในคำตอบสำหรับการอ่านเพิ่มเติม
cprn

4

หากคุณใช้ Kubuntu หรือใช้ KDE / Plasma เป็นเดสก์ท็อปของคุณคุณต้องฟังอินเทอร์เฟซorg.freedesktop.ScreenSaverดังนั้นสคริปต์สำหรับฟังเหตุการณ์นั้นจะมีลักษณะดังนี้:

dbus-monitor --session "type='signal',interface='org.freedesktop.ScreenSaver'" |
  while read x; do
    case "$x" in 
      *"boolean true"*) echo SCREEN_LOCKED;;
      *"boolean false"*) echo SCREEN_UNLOCKED;;  
    esac
  done

1
ถ้าคุณใช้ KDE / พลาสม่าที่คุณสามารถใช้การตั้งค่าพลาสม่าสก์ท็อปในการรันสคริปต์การแจ้งเตือน Personalization>Notifications>Notifications>Screensaver...
xenoid

ขอบคุณ @xenoid! KDE เป็นสิ่งที่ปรับเปลี่ยนได้ตามความต้องการของคุณโดยที่คุณไม่ต้องทำตัวให้ยุ่งกับสิ่งเหล่านี้ ราวกับว่าพวกเขาคาดหวังสิ่งที่ฉันต้องการ
Ankur S

0

upstart การสนับสนุนงานเซสชันdesktop-lockและdesktop-unlockกิจกรรมในstart onstanza เพียงแค่สร้างงาน. ยืนยันสำหรับผู้ใช้ของคุณด้วยทริกเกอร์และคำสั่งที่เกี่ยวข้องในการโทร$XDG_CONFIG_HOME/upstart/หรือ$HOME/.config/upstartตัวอย่างด้านล่าง:

description "some job description"
start on desktop-lock
script
        /path/to/your/executable
end script

-1

นี่คือสิ่งที่ใช้ได้กับฉันใน Ubuntu 16.04

dbus-monitor --session "type=signal,interface=org.gnome.ScreenSaver" | 
  while read MSG; do
    LOCK_STAT=`echo $MSG | grep boolean | awk '{print $2}'`
    if [[ "$LOCK_STAT" == "true" ]]; then
        echo "was locked"
    else
        echo "was un-locked"
    fi
  done

สิ่งนี้ไม่ได้ผลสำหรับฉัน เมื่อเสร็จสิ้นการดำเนินการและไม่ฟังสถานะที่เปลี่ยนแปลง
Starx

คุณกำลังใช้โปรแกรมรักษาหน้าจอใดอยู่ คำพังเพยหรือ xscreensaver? สิ่งที่รสชาติอูบุนตู, xubuntu, kubuntu ฯลฯ ซึ่งรุ่น (มันได้รับการทดสอบเมื่อวันที่ 16.04)
ozma

ubuntu gnome 16.04
Starx
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.