루트 크론 작업이 완료된 후 사용자에게 (zenity/GUI) 대화 상자를 표시하는 방법

루트 크론 작업이 완료된 후 사용자에게 (zenity/GUI) 대화 상자를 표시하는 방법

루트로 실행해야 하는 간단한 주기적인 cron 작업이 있습니다. cron 작업이 완료되면 Zenity(또는 이와 유사한 것)를 사용하여 사용자 1000(또는 로그인한 사용자 또는 모든 사용자)에게 GUI 정보 대화 상자를 표시하고 싶습니다.

저는 간단하고, 쉽고, 빠른 해결책을 찾고 있습니다. 이 간단한 솔루션에 대한 요구 사항을 조정하겠습니다.

이것이 제가 지금까지 있는 곳입니다. 내 bash 스크립트를 수동으로 실행하면 제대로 작동하지만 Anacron이 실행하면 아무 일도 일어나지 않습니다. Gtk-WARNING **: cannot open display로그에 표시됩니다. cron이 실행된 후 사용자에게 내 대화 상자를 표시하고 싶습니다.

(관련 질문을 읽은 후) cron이 GUI에서 분리되어야 한다는 것을 깨달았습니다. 사용자 1000이 로그인되어 있지 않으면 다음 옵션 중 하나를 선택할 수 있습니다.

  1. 아무것도 하지 않음(단순하게 유지하고 싶기 때문에 허용될 수 있음)
  2. 사용자가 다음에 로그인할 때 완료 메시지가 포함된 대화 상자 표시(최적)
  3. 다른 유형의 알림 표시(참고: 컴퓨터는 메일 서버가 설치되지 않은 데스크톱 시스템입니다.)

다음 관련 질문을 찾았습니다: x11 - Anacron 작업에서 "Gtk-WARNING **: 디스플레이를 열 수 없습니다"라고 불평합니다. - Think Tank 101 - CC 저작권에 기반한 Q&A 공유 플랫폼 Anacron 작업에서 "Gtk-WARNING **: 디스플레이를 열 수 없습니다"라고 불평합니다.

shell - zenity 진행을 위해 프로세스 외부로 데이터를 전달하는 방법은 무엇입니까? - Unix 및 Linux 스택 zenity 진행 상황을 얻기 위해 프로세스 외부로 데이터를 전달하는 방법은 무엇입니까?

샘플 코드 (다른 질문에서, 기본적으로 내 코드와 동일):

#!/bin/bash
# Backs up the local filesystem on the external HDD

sleep 60

DISPLAY=:0.0

zenity --question --text "Do you want to backup? Be sure to turn on the HDD."
if [ $? -ne 0 ]
    then exit 1
fi

*Do backup stuff here*

실수:

(zenity:9917): Gtk-WARNING **: cannot open display: 
run-parts: /etc/cron.daily/backup-on-external exited with return code 1

(저는 쿠분투를 사용하고 있어서 KDE 솔루션이 Zenity보다 훨씬 좋은데 이미 Zenity가 설치되어 있어서 계속 사용할 수 있습니다.)

답변1

다음과 같은 것을 귀하의 것 ~/.xinitrc(또는 ~/.xsession로그인 관리자를 사용하는 경우)에 추가해 보십시오:

while true; do
    if [[ -a ~/.messages ]]; then
        zenity --info --text="$(printf "%q" $(cat ~/.messages))"
        rm ~/.messages
    fi
    sleep 10
done &

zenity가 없기 때문에 이것을 테스트하지 않았으며 .xsession예상대로 작동한다고 가정합니다. 로그인 관리자를 사용한 적이 없습니다.

while/block은 done검사 사이에 10초의 지연( sleep 10부분적으로)을 두고 무기한 실행됩니다. 각 검사에서 사용자의 홈 디렉터리에서 if비어 있지 않은 파일이 호출되면 보호가 성공합니다 . .messages성공하면 파일 내용이 zenity로 읽혀지고 삭제됩니다.

토하는 게 별로 기쁘지는 않지만 printf괜찮을 것 같아요.

입력된 내용은 ~/.messagescron에서 리디렉션되어야 하며 파일 소유자와 그룹을 적절하게 변경했는지 확인해야 합니다. 어쩌면 다음과 같은 것일 수도 있습니다.

10 * * * * /usr/bin/mything && echo "mything completed" > /home/username/.messages && chown username:groupname /home/username/.messages

답변2

내 시스템은 우분투 13.04입니다. anacrontab을 통해 귀하와 유사한 스크립트를 실행했는데 작동했습니다. 이 시도..

크론탭을 설정하세요..

$ cat /path/crontabfile
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

*   *   *   *   *   /bin/bash /path/anacron-tst/s1.sh

대안: 아나크론탭을 설정하세요..

$ cat /etc/anacrontab
### original
.. ,, ..
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HOME=/root
LOGNAME=root

# These replace cron's entries
1   5   cron.daily  run-parts --report /etc/cron.daily
7   10  cron.weekly run-parts --report /etc/cron.weekly
@monthly    15  cron.monthly    run-parts --report /etc/cron.monthly
### end-original

### my custom lines ..
SHELL=/bin/bash
HOME=/home/me
LOGNAME=me

1   2   me1 /bin/bash /path/anacron-tst/s1.sh

스크립트에서 ...

$ cat /path/anacron-tst/s1.sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

export DISPLAY=:0.0
export XAUTHORITY=/home/me/.Xauthority

zenity --question --text "Backup time .. is HDD connected?"

if [ $? -ne 0 ]; then
    echo "No confirmation .. quiting"
    exit 1
else
    echo "Will attempt backup now .."
fi

이것은 man 5 anacrontab에서 가져온 것입니다.

.. lines can be of three kinds:  job-description lines, environment assignments, or empty lines.

Environment assignment lines are of the form: VAR = VALUE
.. ,, ..
The assignment takes effect from the next line to the end of the  file,  or
to the next assignment of the same variable.

이는 루트에 설치된 crontab과 함께 사용됩니다. 다음 줄을 포함하도록 스크립트를 편집했습니다."XAUTHORITY=/home/me/.Xauthority 내보내기". 이 방법으로 작업해야 합니다.

답변3

지금까지 내가 찾은 모든 내용에 대한 보고서는 다음과 같습니다.

이 솔루션은 Ask Ubuntu에서 제공됩니다.

이것은 현재 나에게 효과적이며 지금까지는 어떤 문제도 발견되지 않았습니다.

        ACTIVE=$(ck-list-sessions | awk -F' = ' '
            function f(){if(A=="TRUE"){P=U"\t"D;gsub("'"'"'","",P);print P}}
            $1=="\tunix-user"{U=$2} 
            $1=="\tx11-display"{D=$2} 
            $1=="\tactive"{A=$2} 
            END{f()} /^[^\t]/{f()}
        ')
        USERID=${ACTIVE%    *} # tab
        USERNAME=$(getent passwd $USERID|cut -f1 -d':')
        DISPLAY=${ACTIVE#*  } # tab

        DISPLAY="$DISPLAY" su $USERNAME -c "zenity --info --title='My Title' --text='My text. Notice the single quotes.'"

하지만 저는 inform-send 명령을 테스트해 왔습니다(언급됨).여기) 그리고 내 경우에는 더 잘 맞는 것 같습니다 ...

불행하게도 KDE의 단점은 알림이 빨리 숨겨지고 시간 초과를 비활성화하는 방법을 찾지 못했다는 것입니다(-t 0은 작동하지 않습니다). 현재 사용 사례에서는 버튼을 클릭하여 닫아야 하는 대화 상자를 선호하는 경향이 있습니다. 어쨌든 알림 전송 세부정보는 다음과 같습니다.

알림 전송 명령

알림 보내기 명령을 사용하면 알림 데몬을 통해 명령줄에서 사용자에게 데스크톱 알림을 보낼 수 있습니다. 이는 데스크톱 사용자에게 이벤트를 알리거나 사용자를 방해하지 않고 어떤 형태의 정보를 표시하는 데 유용합니다. 다음 패키지를 설치해야 합니다.

$ sudo apt-get install libnotify-bin

이 예에서는 명령줄에서 간단한 데스크톱 알림을 보내려면 다음을 입력합니다.

notify-send "rsnapshot done :)"

하지만 해결책을 찾다가 제가 정말 좋아하는 몇 가지 사실도 발견했습니다! 모든 스크립트에서 Zenity에 대한 모든 호출을 제거하고 easybashgui로 대체하겠습니다.

EasybashGUI

http://sites.google.com/site/easybashgui/

EasyBashGUI는 KDE 또는 Is GNOME running, Yad에 따라 yad, gtkdialog, kdialog, zenity, Xdialog, (c)dialog,hiptail 또는 bash 내장 기능을 사용하여 간단한 GUI 기능을 제공하도록 설계된 *BSD 및 GNU/Linux용 Bash 라이브러리입니다. /Gtkdialog/Xdialog가 설치되고 마지막으로 X 서버가 실행됩니다.

앞으로 Zenity를 대체할 Yad도 찾았습니다. easybashgui는 Zenity, yad, gtkdialog, kdialog, Xdialog, (c)dialog,hiptail 또는 bash 내장 기능을 사용/호출할 수 있습니다. 따라서 저는 Zenity를 단계적으로 폐지하고 적절한 경우 yad를 사용할 것입니다.

마당

쉘 스크립트 또는 명령줄에서 그래픽 대화 상자 표시 - Google Project Hosting http://code.google.com/p/yad/

Yad(Another Dialog)는 사용자 정의 버튼, 추가 대화 상자, 알림 아이콘의 팝업 메뉴 등과 같은 많은 개선 사항이 포함된 Zenity의 포크입니다.

이 포크를 만든 이유는 크게 두 가지입니다. 첫 번째는 libglade 및 gnome-canvas와 같이 더 이상 사용되지 않는 라이브러리에 대한 종속성을 제거하는 것입니다. 둘째 - Zenity는 나에게 버려진 프로젝트처럼 보입니다. 오랫동안 ChangeLog에는 "다음으로 업그레이드된 버전..." 및 "번역 업데이트"만 포함되어 있었지만 개발자/유지관리자가 무시한 많은 흥미로운 아이디어가 GNOME Bugzilla에 있습니다.

공책

don_crissti가 언급했듯이 unix.stackexchange.com의 솔루션이 관련될 수 있습니다.

원격 X 모니터에서 창 열기("모니터를 열 수 없습니다" 이유)?

답변4

Mel Boyce의 답변을 바탕으로 이것이 나에게 효과적이었습니다. 이는 KDE를 기반으로 합니다. 하지만 Zenity로도 테스트했는데 동일한 방법이 작동했습니다. 이것은 기본적으로 Mel Boyce가 권장하는 것과 동일하지만 나에게 적합하도록 몇 가지 조정이 필요합니다. 예를 들어 updateNotification.txt 파일은 삭제하지 않습니다. 그리고 나는 printf를 사용하지 않습니다.

업데이트 프로그램 스크립트에는 다음이 포함됩니다.

DATE_STAMP=` date`
echo "\t***The software has been updated to version ${LATEST} on ${DATE_STAMP}***"
echo "The software has been updated to version ${LATEST} on ${DATE_STAMP}. Please close and reopen the program if it is current running. If you have any issues or questions, please write us at [email protected]. Thank you." > /home/$USERN/.updateNotification.txt

그런 다음 /home/$USERN/.kde/Autostart/updateNotificationChecker.sh에서 스크립트를 실행합니다.

#!/bin/bash
while true; do
    if [[ -s ~/.updateNotification.txt ]]; then
                read MSGFE < ~/.updateNotification.txt 
                kdialog --title 'The software has been updated' --msgbox "$MSGFE"
                cat /dev/null > ~/.updateNotification.txt
    fi
    sleep 300
done
exit 0

관련 정보