ใช้การแจ้งเตือน - ส่งด้วย cron


32

ฉันใช้ Arch Linux กับ KDE / Awesome WM ฉันพยายามที่จะได้รับ ในการทำงานด้วยnotify-sendcron

ฉันได้ลองตั้งค่าDISPLAY/ XAUTHORITYตัวแปรและใช้งานnotify-sendด้วย "sudo -u" โดยไม่มีผลลัพธ์

ฉันสามารถโทรแจ้ง - ส่งแบบโต้ตอบจากเซสชันและรับการแจ้งเตือน

FWIW งาน cron ทำงานได้ดีซึ่งฉันตรวจสอบโดยการสะท้อนสิ่งที่เป็นไฟล์ชั่วคราว มันเป็นเพียง "แจ้ง - ส่ง" ที่ล้มเหลวในการทำงาน

รหัส:

[matrix@morpheus ~]$ crontab -l
* * * * *  /home/matrix/scripts/notify.sh

[matrix@morpheus ~]$ cat /home/matrix/scripts/notify.sh
#!/bin/bash
export DISPLAY=127.0.0.1:0.0
export XAUTHORITY=/home/matrix/.Xauthority
echo "testing cron" >/tmp/crontest
sudo -u matrix /usr/bin/notify-send "hello"
echo "now tested notify-send" >>/tmp/crontest

[matrix@morpheus ~]$ cat /tmp/crontest
testing cron
now tested notify-send

[matrix@morpheus ~]$ 

ในขณะที่คุณสามารถเห็นเสียงสะท้อนก่อน & หลังแจ้งเตือน - ส่งงาน
นอกจากนี้ฉันได้ลองตั้งค่าDISPLAY=:0.0

อัปเดต: ฉันค้นหาอีกเล็กน้อยและพบว่าจำเป็นต้องตั้งค่าDBUS_SESSION_BUS_ADDRESS และหลังจากฮาร์ดโค้ดนี้โดยใช้ค่าที่ฉันได้รับจากเซสชันแบบโต้ตอบข้อความ "สวัสดี" เล็ก ๆ ก็เริ่มโผล่ขึ้นมาบนหน้าจอทุกนาที!

แต่การจับคือตัวแปรนี้ไม่ถาวรต่อโพสต์นั้นดังนั้นฉันจะลองใช้วิธีแก้ปัญหาไพพ์ที่มีชื่อที่แนะนำ

[matrix@morpheus ~]$ cat scripts/notify.sh
#!/bin/bash
export DISPLAY=127.0.0.1:0.0
export XAUTHORITY=/home/matrix/.Xauthority
export DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-BouFPQKgqg,guid=64b483d7678f2196e780849752e67d3c
echo "testing cron" >/tmp/crontest
/usr/bin/notify-send "hello"
echo "now tested notify-send" >>/tmp/crontest

ตั้งแต่cronดูเหมือนจะไม่สนับสนุนการแจ้ง-ส่ง (อย่างน้อยไม่ได้โดยตรง) มีบางระบบการแจ้งเตือนอื่น ๆ ที่มีมากขึ้นcronเป็นมิตรที่ฉันสามารถใช้?


มันน่าจะใช้ได้เท่าที่ฉันเห็น ทำไมคุณไม่เพิ่ม&>>/tmp/crontestในบรรทัดแจ้งเตือนเพื่อดูว่าnotify-sendมีข้อความแสดงข้อผิดพลาดหรือไม่
แกรม

คุณลองใช้วิธีการแก้ปัญหาของฉันด้วยความอยากรู้ไหม? ดูเหมือนง่ายกว่ามากและทำงานอย่างสมบูรณ์บนเดเบียนของฉัน ฉันแค่ขอให้รู้ว่ามันเป็น Debian เฉพาะหรือไม่
terdon

@terdon ฉันลองใช้วิธีแก้ปัญหาของคุณ (แค่ทดสอบอย่างรวดเร็ว) และดูเหมือนว่าจะทำงานกับระบบ Debian ของฉัน ฉันอยากรู้ว่ามันใช้งานได้จริงหรือไม่เพราะมันง่ายกว่า
Marco

@ มาร์โกฉันอยู่ใน LMDE (ทดสอบเดเบียนเป็นหลัก) และใช้อบเชยเป็น DE ไม่สามารถบอกคุณได้ว่ามันทำงานเหนือกว่านั้นหรือไม่
terdon

@Marco & terdon: พวก Ubuntu สามารถทำได้: ubuntuforums.org/showthread.php?t=1727148
justsomeone

คำตอบ:


29

คุณต้องตั้งค่าDBUS_SESSION_BUS_ADDRESSตัวแปร โดยค่าเริ่มต้น cron ไม่สามารถเข้าถึงตัวแปร ในการแก้ไขปัญหานี้ให้วางสคริปต์ต่อไปนี้ไว้ที่ใดที่หนึ่งและเรียกใช้เมื่อผู้ใช้ลงชื่อเข้าใช้ตัวอย่างเช่นการใช้คำสั่งที่เยี่ยมยอดและrun_onceฟังก์ชั่นกล่าวถึงในวิกิพีเดีย วิธีการใด ๆ ที่จะทำเพราะมันจะไม่เป็นอันตรายหากฟังก์ชั่นที่เรียกว่าบ่อยกว่าที่จำเป็น

#!/bin/sh

touch $HOME/.dbus/Xdbus
chmod 600 $HOME/.dbus/Xdbus
env | grep DBUS_SESSION_BUS_ADDRESS > $HOME/.dbus/Xdbus
echo 'export DBUS_SESSION_BUS_ADDRESS' >> $HOME/.dbus/Xdbus

exit 0

สิ่งนี้จะสร้างไฟล์ที่มีตัวแปร Diron evironment จากนั้นในสคริปต์ที่เรียกโดย cron คุณนำเข้าตัวแปรโดยการจัดหาสคริปต์:

if [ -r "$HOME/.dbus/Xdbus" ]; then
  . "$HOME/.dbus/Xdbus"
fi

นี่คือคำตอบที่ใช้กลไกเดียวกัน


1
ดีใจที่ได้เห็นว่าฉันใกล้จะแก้ปัญหาแล้ว ขอบคุณมาร์โกที่เรียบร้อย!
justsomeone

เยี่ยมมากฉันใช้คำตอบของคุณซ้ำและเพิ่มคำแนะนำโดยละเอียดเพิ่มเติมได้ที่นี่: askubuntu.com/a/537721/34298
rubo77

สิ่งนี้จะไม่เป็นความเสี่ยงด้านความปลอดภัยหรือไม่ security.stackexchange.com/questions/71019/…
rubo77

@Gilles คุณสามารถทำสิ่งนี้ในหนึ่งบรรทัดเหมือนที่คุณพูดถึงในการแชทได้อย่างไร?
rubo77

ฉันได้ลองคำตอบอื่น ๆ มากมายไม่รวม DBUS บน Ubuntu 15.10 และไม่มีอะไรทำงาน อันนั้นง่ายและทำงานได้อย่างไร้ที่ติ
bastian

16

คุณต้องตั้งค่าตัวแปรใน crontab เอง:

DISPLAY=:0.0
XAUTHORITY=/home/matrix/.Xauthority

# m h  dom mon dow   command 
* * * * *  /usr/bin/notify-send "hello"

ไม่sudoต้องการอย่างน้อยไม่ได้อยู่ในระบบของฉัน


ขอบคุณ terdon สำหรับเวลาของคุณ นี่ดูเหมือนจะเป็นทางออกที่ง่าย น่าเสียดายที่นี่ใช้งานไม่ได้สำหรับฉัน
justsomeone

@justsomeone huh, OK อาจขึ้นอยู่กับสภาพแวดล้อมเดสก์ทอป
terdon

ฉันคิดว่านี่มีบางอย่างเกี่ยวกับ distro หรือ Desktop Environment สำหรับผู้ใช้งาน Ubuntu โซลูชันตรงไปตรงมาดูเหมือนจะทำงานได้ดีจากสิ่งที่ฉันเห็นในฟอรัมออนไลน์
justsomeone

@justsomeone ฉันใช้ Debian (LMDE) โดยใช้ Cinnamon เป็น DE อาจมีบางอย่างที่เกี่ยวข้องกับวิธีที่ X เริ่มต้นทำงานหรือกับระบบการแจ้งเตือนที่ใช้โดย DE หรือไม่
terdon

ยืนยันว่าใช้งานได้บน Ubuntu 14.04 / 14.10 ด้วย GNOME และ Unity
Jordon Bedwell

8

วิธีที่ปลอดภัยที่สุดในการรับ X สิ่งแวดล้อมที่เกี่ยวข้องกับตัวแปรสิ่งแวดล้อมคือการได้มาจากสภาพแวดล้อมของกระบวนการของผู้ใช้ที่เข้าสู่ระบบ X นี่คือการปรับตัวของสคริปต์ที่ฉันใช้เพื่อจุดประสงค์เดียวกัน (แม้ว่า DBUS_SESSION_BUS_ADDRESS ไม่ได้ ' ดูเหมือนจะไม่เป็นปัญหาสำหรับฉันใน Debian):

X=Xorg                   # works for the given X command
copy_envs="DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS"

tty=$(ps h -o tty -C $X | head -1)
[ -z "$tty" ] && exit 1

# calling who with LANG empty ensures a consistent date format
who_line=$(LANG= who -u | grep "^[^ ]\+[ ]\+$tty")

x_user=$(echo $who_line | cut -d ' ' -f 1)  # the user associated with the tty
pid=$(echo $who_line | cut -d ' ' -f 7)     # the user's logon process

for env_name in $copy_envs
do
  # if the variable is not set in the process environment, ensure it does not remain exported here
  unset "$env_name"

  # use the same line as is in the environ file to export the variable
  export "$(grep -az "^$env_name=" /proc/$pid/environ)" >/dev/null
done

sudo -u "$x_user" notify-send "hello"

สิ่งนี้จะส่งข้อความไปยังผู้ใช้ X คนแรกที่พบแม้ว่าคุณสามารถเพิ่มการวนซ้ำเพื่อส่งไปยังผู้ใช้ทั้งหมด

ปรับปรุง

ดูเหมือนว่าการอัพเดตรูปแบบ utmp ทำให้เกิดwhoการพิมพ์จอแสดงผลแทน tty ในคอลัมน์ที่สอง สิ่งนี้ทำให้ง่ายขึ้นจริง ๆ ก่อนหน้านี้มันจะพิมพ์เฉพาะการแสดงผลในความคิดเห็นตอนท้ายและฉันคิดว่ามันไม่ปลอดภัยที่จะไว้ใจคำตอบเดิม หากเป็นกรณีนี้ลองสิ่งนี้:

X=Xorg                   # works for the given X command
copy_envs="DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS"

# calling who with LANG empty ensures a consistent date format
who_line=$(LANG= who -u | awk '$2 ~ ":[0-9]"')

x_user=$(echo $who_line | cut -d ' ' -f 1)  # the user associated with the tty
pid=$(echo $who_line | cut -d ' ' -f 7)     # the user's logon process

for env_name in $copy_envs
do
  # if the variable is not set in the process environment, ensure it does not remain exported here
  unset "$env_name"

  # use the same line as is in the environ file to export the variable
  export "$(grep -az "^$env_name=" /proc/$pid/environ)" >/dev/null
done

sudo -u "$x_user" notify-send "hello"

สิ่งนี้ใช้ไม่ได้กับ Trusty เพราะไม่มีwho_lineคำสั่งtty ที่พิมพ์ออกมา me :0 2015-09-23 10:40 ? 17234เอาท์พุทดูเหมือน
blujay

1
@blujay อัปเดตแล้ว
แกรม

ขอบคุณที่ใช้งานได้ อย่างไรก็ตามในขณะที่ฉันโพสต์ในคำตอบแยกต่างหากมีวิธีแก้ปัญหาที่ง่ายกว่า
blujay

@blujay ใช่นี่เป็นความพยายามในการตอบคำถามแบบพกพา ไม่แน่ใจว่านี่เป็นไปได้จริง ๆ แต่ก็ควรจะทำงานในกรณีส่วนใหญ่
แกรม

2

สิ่งนี้ใช้ได้กับฉันใน Manjaro กับ Cronie:

# Note: "1000" would be your user id, the output of... "id -u <username>" 
10 * * * * pj DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus notify-send 'Hello world!' 'This is an example notification.'

โดยไม่ต้อง DBUS_blah_blah น่าเกลียดมากมันไม่ทำงานเลย ฉันก็พบว่ามีjournalctl -xb -u cronieประโยชน์ ฉันยังไม่คุ้นเคยกับ Cronie แต่สร้าง "crontab" ของ/etc/cron.d/mycronjobsฉันและฉันไม่แน่ใจว่าจำเป็นต้องใช้ชื่อไฟล์นั้นหรือไม่หรืออ่านทุกอย่างในไดเรกทอรี cron.d

ฉันพบวิธีแก้ปัญหาที่นี่https://wiki.archlinux.org/index.php/Desktop_notifications



1

นี่เพียงพอที่จะทำให้การแจ้งเตือน - ส่งงานให้ฉันใน cronjob บน Ubuntu Trusty:

#!/bin/bash
export DISPLAY=$(who -u | awk  '/\s:[0-9]\s/ {print $2}')

มันเพียงแค่ส่งออกDISPLAYสำหรับผู้ใช้ cronjob กำลังทำงานเป็น การทำงานสำหรับฉันโดยไม่ต้องตั้งค่าหรือXAUTHORITYDBUS_SESSION_BUS_ADDRESS


1
ทำงานบน Ubuntu 16.04 เช่นกัน จริง ๆ แล้วฉันมี cron เปิดตัวสคริปต์ Perl ซึ่งเป็นระบบ () sa bash script ซึ่งเปิดตัวสคริปต์ Perl ที่แตกต่างกันซึ่งดำเนินการระบบ ("แจ้งเตือน - ส่ง ... ") การเพิ่มคำสั่งส่งออกไปยังสคริปต์ทุบตีแก้ไขสภาพแวดล้อมสำหรับสคริปต์นั้นซึ่งสคริปต์ Perl ล่าสุดนั้นสืบทอดและทำให้พร้อมใช้งานกับระบบ ("แจ้งเตือน - ส่ง ... ") หา blujay ดี!
ทิม

1

สำหรับผู้ที่ใช้งาน Linux ที่ติดตั้งแพ็คเกจ Python ได้อย่างสะดวกสบายฉันเพิ่งเปิดตัวโปรแกรมแจ้งเตือน - ส่ง - หัวขาดซึ่งทำงานได้ดีสำหรับฉัน มันค้นหา/procชื่อผู้ใช้และตัวแปรสภาพแวดล้อมที่ต้องการแล้วทำงานnotify-sendกับตัวแปรเหล่านี้ (มันจะใช้sudoเพื่อสลับไปยังผู้ใช้ที่จำเป็นหากจำเป็น)


1

คุณสามารถสร้างสคริปต์:

#!/usr/bin/env bash
runuser -l [yourusername] -c 'DISPLAY=:0 notify-send "hey there user"'

sudoจากนั้นเรียกมันด้วย อย่างไรก็ตามเนื่องจากcrontab -eรันคำสั่งทั้งหมดด้วยผู้ใช้ที่สร้างขึ้นคำสั่งต่อไปนี้น่าจะเพียงพอเมื่อมีการเรียกโดยไม่มีsudo:

#!/usr/bin/env bash
DISPLAY=:0 notify-send "hey there user"

อย่างน้อยก็สำหรับฉัน ดูเหมือนว่าทั้งหมดจะขึ้นอยู่กับการกำหนดค่าสภาพแวดล้อม


0

ฉันใช้สคริปต์นี้ใน cron เพื่อโพสต์ MPD ตอนนี้เล่นเพื่อพูดเบาและรวดเร็วทุกชั่วโมง

#!/bin/bash
export DISPLAY=":0.0"
msg=$(mpc current -h 192.168.1.33)
twitter set "#MPD Server nowplaying $msg :  http://cirrus.turtil.net:9001"
#ttytter -status="#MPD Server nowplaying $msg. http://cirrus.turtil.net:9001"

exit 

สคริปต์ที่คล้ายกันโดยใช้การแจ้งเตือน - ส่ง

#!/bin/bash
export DISPLAY=":0.0"
notify-send -i ~/.icons/48arch.png 'OS- Archlinux x86_64 : DWM Window Manager' 'Installed on Sun Apr 21 2013 at 18:17:22' 
exit

คุณอาจประสบปัญหาเนื่องจาก KDE ใช้การแจ้งเตือน deamon IIRC ของตนเอง


0

สำหรับสิ่งที่คุ้มค่า ....

ฉันต้องใช้สิ่งต่อไปนี้กับ Debian Jessie เพื่อให้สิ่งนี้ทำงาน ...

export DISPLAY=:0.0
export HOME=/home/$user
source "$HOME/.dbus/session-bus/*-0"

การออกจากสิ่งเหล่านี้ทำให้หยุดทำงาน


บรรทัดสุดท้ายนั้นจะไม่ทำสิ่งใดตามที่เขียนไว้ที่นี่เพราะจะไม่มีไฟล์ใดที่เรียกว่า*-0ในsession-busไดเรกทอรีของคุณ source "$HOME"/.dbus/session-bus/*-0คุณอาจมีความหมาย
roaima

0

ใช้ sudo:

sudo -u $currentxuser notify-send $message

เคล็ดลับ:

เราสามารถรับผู้ใช้ x ปัจจุบันโดยคำสั่งนี้

ps auxw | grep -i screen | grep -v grep | cut -f 1 -d ' '

นอกจากนี้ ...

currentxuser=$(ps auxw | grep -i screen | grep -v grep | cut -f 1 -d ' ')
echo $currentxuser

ดีแล้วที่รู้ :

Cron ที่ทำงานภายใต้รูทไม่สามารถเข้าถึง x ดังนั้นคำสั่ง gui ทั้งหมดจะไม่ถูกแสดงวิธีแก้ปัญหาอย่างหนึ่งคือการเพิ่มรูทไปยังผู้ใช้ x ที่ได้รับอนุญาตสำหรับผู้ใช้ x ปัจจุบันด้วยคำสั่งนี้

จากเชลล์ผู้ใช้ x

xhost local:root

หรือ

sudo -u $currentxuser xhost local:root

-1

นี่คือสคริปต์ที่ซับซ้อนน้อยกว่าที่ Graeme ให้ไว้ สคริปต์ของเขาใช้งานไม่ได้สำหรับฉันและ$who_lineว่างเปล่าเสมอ สคริปต์ของฉันไม่เสียเวลามากนักในการค้นหากระบวนการ แต่จะลองทั้งหมดและเลือกค่าที่มีประโยชน์ล่าสุดที่พบ ฉันใช้ xubuntu 14.04 และมี lxc container บางตัวที่ใช้งานอยู่ซึ่งอาจสร้างความสับสนให้กับสคริปต์ประเภทนี้

env="$(
  ps -C init -o uid,pid | while read u p; do
    [ "$u" = "`id -u`" ] || continue
    grep -az '^DBUS_SESSION_BUS_ADDRESS=' /proc/$p/environ | xargs -0
  done | tail -1
)"

export "$env"

notify-send "test"

สิ่งนี้ใช้ไม่ได้กับ Trusty เพราะสภาพแวดล้อมของกระบวนการ Xorg ไม่มี DBUS_SESSION_BUS_ADDRESSของไม่ได้ ฉันสามารถหาได้จากกระสุนของฉัน แต่ไม่ใช่จากกระบวนการ Xorg
blujay
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.