Chạy script trên khóa / mở khóa màn hình


54

Tôi muốn chạy một màn hình nếu phiên Gnome bị khóa và mở khóa. Có cách nào để tôi có thể chặn điều này và thực hiện một số hành động nhất định khi máy tính để bàn bị khóa hoặc mở khóa không?

Câu trả lời:


49

Gnome-Screensaver phát ra một số tín hiệu trên dbus khi có điều gì đó xảy ra.

Đây là tài liệu (với một số ví dụ).

Bạn có thể viết một tập lệnh chạy:

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

và đó là những gì bạn cần bất cứ lúc nào dbus-monitorin một dòng về màn hình bị khóa / mở khóa.


Đây là một lệnh bash để làm những gì bạn cần:

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

Chỉ cần thay thế echo SCREEN_LOCKEDecho SCREEN_UNLOCKEDvới những gì bạn cần.


Xin chào @peoro, Điều đó khiến tôi nghĩ rằng bạn có thể mở khóa hoặc khóa màn hình / phiên gnome từ một chương trình kịch bản, đáng để thực hiện một số thủ thuật ssh về nó ;-)
Nikhil Mulley

1
@Nikhil: để làm điều đó bạn không cần phải chơi xung quanh với dbus: gnome-screensaver-commandđã có sẵn. Chuyển -ađến gnome-screensaver-commandbạn sẽ khóa màn hình, trong khi bạn sẽ mở khóa bằng -d. Dù sao, hầu hết các ứng dụng gnome đều sử dụng dbus rộng rãi, vì vậy bạn sẽ có thể làm nhiều điều tuyệt vời với nó.
peoro

1
@peoro Cảm ơn rất nhiều, rất hữu ích! Tôi cũng có thể chạy nó như một loại daemon? Khi tôi nhập cái này vào thiết bị đầu cuối bây giờ, nó phải mở để theo dõi dbus cho trường hợp đó. Tôi muốn thực thi lệnh này khi đăng nhập và sau đó nó có thể được kích hoạt trong toàn bộ phiên.
Sander

1
Tôi nghĩ mọi thứ có thể đã thay đổi trong năm 2014? vì đầu ra không thay đổi nếu màn hình chỉ bị khóa, nó chỉ hiển thị một cái gì đó khi nó bị trống và rất khác so với ở đây :(, tôi đã tạo ra câu hỏi này Askubfox.com/questions/505681/ , bạn có tin rằng vẫn còn một số Cách để làm điều đó? thx!
Sức mạnh của Bảo Bình

Làm thế nào để chạy tập lệnh mà nó bắt được sự kiện khóa? Kinda như một người theo dõi.
Starx

20

Trong phiên bản Ubuntu 14.04, sự kiện DBus để mở khóa khóa màn hình đã thay đổi và tập lệnh mới để liên kết với khóa màn hình và mở khóa các sự kiện giống như sau

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
)

ý tưởng về cách làm cho công việc này trên fedora 23?
Ray Foss

2
Hoạt động tốt vào ngày 16.04 cũng vậy
Jacob Vlijm

@JacobVlijm Cảm ơn bạn đã thử nghiệm cái này và bật đèn xanh cho tôi sử dụng tối nay :)
WinEunuuchs2Unix

6

Ngày nay tôi nghĩ tốt hơn là nên nghe những LockedHinttin nhắn thay vì bảo vệ màn hình. Bằng cách đó, bạn không bị ràng buộc với việc thực hiện bảo vệ màn hình.

Đây là một kịch bản đơn giản để làm điều đó:

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

Đưa ra điều này:

/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: giải pháp của ozma không hiệu quả với tôi, tuy nhiên giải pháp này đã làm:

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

Nó có thể hoạt động trên Unity nhưng câu hỏi liên quan đến Gnome.
cprn

5

Mở rộng về câu trả lời đã được đưa ra.

Nếu bạn cố chạy tập lệnh từ bên trong một phiên screenhoặc tmuxphiên, bạn sẽ cần tìm chính xác $DBUS_SESSION_BUS_ADDRESStrước và chuyển nó thành đối số dbus-monitorthay vì --session. Ngoài ra, nếu bạn đang chạy nó như một daemon, bạn nên đảm bảo chỉ có một phiên bản đang chạy tại một thời điểm (ví dụ: với một tệp khóa) và tập lệnh sẽ tự dọn sạch trap. Ví dụ sau sẽ hoạt động như một trình nền trong hầu hết các môi trường Gnome hiện tại (được thử nghiệm trên 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)

Nếu điều này không phù hợp với bạn, có lẽ là vì:

  1. bạn không sử dụng Gnome - kiểm tra các câu trả lời khác để có biểu hiện đồng hồ DBus tốt hơn.
  2. bạn chạy nhiều dòng DBus - kiểm tra chi tiết về cách làm cho việc tìm kiếm PID trở nên xác định.

1
Điều này thực sự trả lời một câu hỏi khác mà tôi đã có khi tự động khám phá thông tin phiên DBus được cung cấp tài khoản người dùng mà tôi đã giải quyết ở đây . Cảm ơn sự đóng góp của bạn ở đây!
Naftuli Kay

Cảm ơn. Tôi sẽ liên kết giải pháp của bạn trong câu trả lời để đọc thêm.
cprn

4

Nếu bạn đang sử dụng Kubfox hoặc sử dụng KDE / Plasma làm Môi trường máy tính để bàn, bạn phải lắng nghe giao diện org.freedesktop.ScreenSaver, do đó, tập lệnh để nghe sự kiện đó sẽ như thế này:

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
Nếu bạn sử dụng KDE / Plasma, bạn có thể sử dụng các thiết lập Plasma Desktop để thực hiện kịch bản trên thông báo ... Personalization>Notifications>Notifications>Screensaver.
xenoid

cảm ơn @xenoid! KDE là một de de cá nhân hóa mà bạn không bao giờ phải nghịch ngợm với những điều này. cứ như thể họ dự đoán những gì tôi cần
Ankur S

0

upstart phiên hỗ trợ công việcdesktop-lockdesktop-unlockcác sự kiện trong khổ start onthơ. Chỉ cần tạo một công việc .conf cho người dùng của bạn bằng các trình kích hoạt và lệnh có liên quan để gọi theo $XDG_CONFIG_HOME/upstart/hoặc $HOME/.config/upstartví dụ dưới đây:

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

-1

đây là những gì làm việc cho tôi trong 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

Điều này đã không làm việc cho tôi. Khi nó thực hiện xong và không lắng nghe trạng thái thay đổi.
Starx

bạn đang sử dụng trình bảo vệ màn hình nào? gnome hay xscreenaver? hương vị nào ubfox, xubfox, kubfox, v.v. phiên bản nào (đã được thử nghiệm vào ngày 16.04)
ozma

ubfox gnome 16.04
Starx 2/11/2016
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.