명령줄을 사용하여 실행 중인 모든 X 모니터에 알림을 표시하고 싶습니다. (그리고 콘솔 실행)
그것은 다음과 같습니다:
notify-send-all 'Warning' 'Nuclear launch in 5 minutes, please evacuate'
이것을 할 수 있는 프로그램이 있나요? 그렇지 않다면 bash를 사용하여 구현할 수 있습니까?
답변1
Command Wall을 사용하여 모든 콘솔에 메시지를 보낼 수 있습니다.
X에서 알림을 보내려면 알림 보내기를 사용하여 현재 모니터의 현재 사용자에게 알림을 보낼 수 있습니다. (귀하의 질문으로 판단하면 이미 알고 계실 것 같습니다.) 일부 bash 스크립트를 사용하여 이를 구축할 수 있습니다. 기본적으로 어떤 사용자가 어떤 X-Display에 있는지 알아내야 합니다. 이 정보가 있으면 다음과 같은 알림을 사용하여 보낼 수 있습니다.
DISPLAY=:0 sudo -u fschmitt notify-send "Message"
여기서 fschmitt는 디스플레이 0의 사용자입니다. "who" 명령의 출력을 구문 분석하여 모든 사용자와 해당 디스플레이를 찾을 수 있습니다. 출력은 다음과 같습니다
[edinburgh:~]$ who
markmerk3 tty7 2010-09-23 10:59 (:0)
markmerk3 pts/1 2010-09-30 13:30 (:0.0)
fschmitt pts/2 2010-10-08 11:44 (ip-77-25-137-234.web.vodafone.de)
markmerk3 pts/0 2010-09-29 18:51 (:0.0)
seamonkey pts/6 2010-09-27 15:50 (:1.0)
markmerk3 pts/5 2010-09-27 14:04 (:0.0)
seamonkey tty8 2010-09-27 15:49 (:1)
markmerk3 pts/13 2010-09-28 17:23 (:0.0)
markmerk3 pts/3 2010-10-05 10:40 (:0.0)
X 세션을 실행하는 두 명의 사용자, 즉 모니터 0의 markmerk3과 모니터 1의 seamonkey가 있음을 알 수 있습니다. 내 생각에는 tty[0-9]*를 grep한 다음 줄 끝에 (:[0 -9.]*)가 있는지 확인하여 콘솔 로그인을 제거하고 디스플레이 ID를 추출해야 한다고 생각합니다. 괄호 사이에 문자열이 있습니다.
답변2
이 게시물은 약간 오래되었습니다. 죄송합니다. 하지만 이 주제에 유용한 내용을 추가할 수 있기를 바랍니다. (Josef Kufner도 멋진 스크립트를 작성했는데 나에게는 너무 길었고 PHP를 사용했습니다.)
또한 원래 질문(모든 활성 X 사용자에게 메시지 보내기)에 설명된 도구가 필요합니다. 여기에 있는 답변을 바탕으로 활성 X 사용자를 검색한 who
다음( 를 사용하여) notify-send
각 활성 사용자에 대해 실행하는 작은 bash 전용 스크립트를 작성했습니다.
가장 좋은 점은 모든 매개변수와 함께 "notify-send"와 같은 스크립트를 사용할 수 있다는 것입니다! ;-)
모든 사람에게 알림이 전송되었습니다:
#!/bin/bash
PATH=/usr/bin:/bin
XUSERS=($(who|grep -E "\(:[0-9](\.[0-9])*\)"|awk '{print $1$NF}'|sort -u))
for XUSER in "${XUSERS[@]}"; do
NAME=(${XUSER/(/ })
DISPLAY=${NAME[1]/)/}
DBUS_ADDRESS=unix:path=/run/user/$(id -u ${NAME[0]})/bus
sudo -u ${NAME[0]} DISPLAY=${DISPLAY} \
DBUS_SESSION_BUS_ADDRESS=${DBUS_ADDRESS} \
PATH=${PATH} \
notify-send "$@"
done
위의 코드를 이라는 파일에 복사하고 notify-send-all
실행 가능하게 만든 후 다음 위치에 복사합니다./usr/local/bin
또는/usr/bin
(원하는 대로). 그런 다음 다음과 같이 콘솔 세션에서 루트로 실행하십시오.
notify-send-all -t 10000 "Warning" "The hovercraft is full of eels!"
저는 지금까지 아무런 문제 없이 몇 달 동안 다른 컴퓨터에서 사용해 왔으며 MATE 및 Cinnamon 데스크톱을 사용하여 테스트했습니다. 또한 cron 및 anacron에서도 성공적으로 실행했습니다.
저는 이 스크립트를 Arch Linux용으로 작성했습니다. 다른 Linux 배포판이나 데스크톱에서 문제가 발생하면 알려 주시기 바랍니다.
답변3
Ubuntu 16.04에서는 루트로 실행되는 crontab 스크립트로부터 알림을 받고 싶습니다. 환경 변수를 설정한 후 sudo -u $user
어떤 이유로 작동하지 않았지만 sh -c "..." $user
작동했습니다.
그래서 저는 이제 이 기능을 사용합니다:
notify_all() {
local title=$1
local msg=$2
who | awk '{print $1, $NF}' | tr -d "()" |
while read u d; do
id=$(id -u $u)
. /run/user/$id/dbus-session
export DBUS_SESSION_BUS_ADDRESS
export DISPLAY=$d
su $u -c "/usr/bin/notify-send '$title' '$msg'"
done
}
DBUS_SESSION_BUS_ADDRESS 변수를 찾는 방법은 배포판에 따라 다를 수 있습니다. Ubuntu 16.04에서는 에 위치하며 /run/user/$UID/dbus-session
간단히 얻을 수 있습니다. id -u
에서 반환한 사용자 이름에서 UID를 가져오기 위해 위 함수에서 사용되었습니다 who
.
답변4
다음은 Andy의 스크립트에 대한 업데이트입니다. 결정 방식이 DBUS_SESSION_BUS_ADDRESS
Centos 7에서 작동하지 않습니다. 또한 who
어떤 이유로 인해 명령이 일부 세션을 나열하지 않았기 때문에 ps aux
대신 출력을 구문 분석했습니다. 이 스크립트는 사용자가 X2GO( )를 사용하여 로그인했다고 가정 nxagent
하지만 다른 경우에 맞게 조정하는 것이 간단해야 합니다.
#!/bin/bash
PATH=/usr/bin:/bin
NOTIFY_ARGS='-u critical "Shutdown notice" "THE SYSTEM IS GOING DOWN TODAY AT 23:00.\nWe recommend you to save your work in time\!" -i /usr/share/icons/Adwaita/32x32/devices/computer.png -t 28800000'
function extract_displays {
local processes=$1
processes=$(printf '%s\n' "$processes" | grep -P "nxagent.+:\d+")
ids=$(printf '%s\n' "$processes" | grep -oP "\W\K:(\d)+")
echo $ids
}
function find_dbus_address {
local name=$1
PID=$(pgrep 'mate-session' -u $name)
if [ -z "$PID" ]; then
PID=$(pgrep 'gnome-session' -u $name)
fi
if [ -z "$PID" ]; then
PID=$(pgrep 'xfce4-session' -u $name)
fi
exp=$(cat /proc/$PID/environ | grep -z "^DBUS_SESSION_BUS_ADDRESS=")
echo $exp
}
PROCESSES=$(ps aux)
DISPLAY_IDS=$(extract_displays "$PROCESSES")
echo "Found the following DISPLAYS: $DISPLAY_IDS"
for DISPLAY in $DISPLAY_IDS; do
NAME=$(printf '%s\n' "$PROCESSES" | grep -P "nxagent.+$DISPLAY" | cut -f1 -d ' ')
DBUS_ADDRESS=$(find_dbus_address $NAME)
echo "Sending message to NAME=$NAME DISPLAY=$DISPLAY DBUS_ADDRESS=$DBUS_ADDRESS"
echo "NOTIFY_ARGS=$NOTIFY_ARGS"
eval sudo -u ${NAME} DISPLAY=${DISPLAY} ${DBUS_ADDRESS} PATH=${PATH} notify-send $NOTIFY_ARGS
done