
我有一個守護進程,在 bash 中實現並透過和cron
選項@reboot
運行,該選項顯示不活動的桌面。腳本如下(出於測試目的,時間很短):
#!/bin/bash
P_STATE=0
while :
do
sleep 5
if [ $P_STATE == 0 ]; then
[ `xprintidle` -ge 25000 ] && P_STATE=1 && wmctrl -k on
else
[ `xprintidle` -le 25000 ] && P_STATE=0
done
問題:例如,如果使用者仍在登入畫面中,xprintidle
並且wmctrl
由於桌面尚未載入而失敗。為了避免這種情況,我將以下幾行放在腳本的最開頭:
while:
do
sleep 10s
[ -n `who | grep "$USER"` ] && break
done
因此,腳本等待使用者(USER 變數在 crontab 檔案中設定為我的使用者名稱)被記錄。但是,如果使用者開始終端會話(而不是像 KDE 或 GNOME 這樣的圖形會話),腳本也會繼續。
如何確定使用者是否已經處於能夠「顯示桌面模式」的「圖形」會話中?此外,我如何確保“圖形”會話已完全加載,而不是正在加載或類似的情況?
我的解決方案:
我的(非正式)解決方案是在主循環中添加以下grep
行:
WAIT_TIME=180
while:
do
sleep $WAIT_TIME
[ ! -n "`ps -ef | grep "$WM_CMD" | grep -v "grep"`" ] && continue
## My actions here
done
成為「$WM_CMD」目標視窗管理器命令。我假設,如果視窗管理器命令正在系統中運行,這意味著桌面已完全加載並且任何“圖形”命令都是確定的。
WM_CMD 變數在哪裡定義?在行中crontab
:
@reboot DISPLAY=:0 WM_CMD=/usr/bin/gnome-shell exec script_path/myscript.sh &> /dev/null
但我也認為可以透過其他系統請求來偵測「Windows 管理器命令」。然而,對我來說,在 crontab 檔案中定義 WM_CMD 就足夠了。
答案1
logind
嘗試使用D-Bus從服務中查詢會話資訊。它具有org.freedesktop.login1.Manager
與多種信號的接口,例如SessionNew
和SeatNew
。org.freedesktop.login1.Seat
和org.freedesktop.login1.User
接口。它可以幫助獲取會話/席位/使用者狀態。
答案2
使用登入會話啟動腳本~/.xprofile
為您建立一些標誌檔案。是的~/.xlogin_flag
,然後在您的其他腳本中使用inotifywatch
from packageinotify-tools
來查看它的建立、觸摸或刪除。
答案3
檢查w
命令的輸出。您將在 LOGIN@ 欄位中看到登入類型(X 顯示)。
答案4
檢查 lightdm 的運行時目錄。在有 systemd 和 lightdm 的 Arch 上,當使用者登入時,會建立一個 xauthority 檔案。
$ whoami
carl
$ sudo ls -al /run/lightdm/carl
total 4
drwx------ 2 carl carl 60 Dec 11 19:40 .
drwx--x--x 8 lightdm lightdm 160 Dec 11 19:40 ..
-rw------- 1 carl carl 55 Dec 11 19:40 xauthority
您可以在 while 循環中使用類似的東西來測試這一點。
[[ -f /run/lightdm/${USER}/xauthority ]] && continue