답변:
커맨드 월을 사용하여 모든 콘솔에 메시지를 보낼 수 있습니다.
X 아래에 알림을 보내려면 현재 디스플레이에서 현재 사용자에게 알림을 보내는 알림 보내기가 있습니다. (질문에서 이미 알고있는 것 같습니다.) bash 스크립트를 사용하여이를 만들 수 있습니다. 기본적으로 어떤 사용자가 어떤 X 디스플레이에 있는지 확인해야합니다. 이 정보를 얻으면 다음과 같이 알림 보내기를 사용할 수 있습니다.
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를 추출하십시오.
who
은 로그인 한 사람과 로그인 한 X 디스플레이를 알려줍니다. 약간 필터링해야 할 수도 있습니다.
who | awk '/\(:[0-9]+\)/ {gsub("[:|(|)]","");print "DISPLAY=:"$5 " sudo -u " $1 " notify-send \"Message\""}' | bash
있습니다. 또한, unix.stackexchange.com/questions/1596/…
이 글타래는 조금 낡았지만 죄송합니다. 그래도 주제에 유용한 것을 추가 할 수 있기를 바랍니다. (또한 Josef Kufner는 멋진 스크립트를 작성했습니다. 맛이 너무 길어서 PHP를 사용합니다)
또한 원래 질문에 설명 된대로 모든 활성 X 사용자에게 메시지를 보내려면 도구가 필요했습니다. 그리고 여기에 대한 답변을 바탕 으로이 작은 bash 전용 스크립트를 작성했습니다.이 스크립트는 활성 X 사용자 ( 'who'사용)를 검색 한 다음 모든 활성 사용자에 대해 알림 보내기를 실행합니다.
그리고 가장 좋은 점은 모든 매개 변수를 사용하여 "notify-send"와 같은 스크립트를 사용할 수 있다는 것입니다. ;-)
알림-모두 보내기 :
#!/bin/bash
PATH=/usr/bin:/bin
XUSERS=($(who|grep -E "\(:[0-9](\.[0-9])*\)"|awk '{print $1$5}'|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 내에서 성공적으로 실행합니다.
ArchLinux 용 / 아래에이 스크립트를 작성 했으므로 다른 Linux 배포판 또는 데스크탑에 문제가 있는지 알려주십시오.
|egrep
?? egrep는 명령입니까?
awk '{print $1$5}'
을 사용하는 것이 좋습니다 . 다음은 또한 모든 사용자 대신 특정 사용자에게 알리는 버전입니다. gist.github.com/shvchk/ba2f0da49bf2f571d6bf606d96f289d7awk '{print $1$NF}'
Jun 3
2017-06-03
grep -E
하고 /bin
경로에 추가 한 후 우분투에서 훌륭하게 작동 합니다 (편집 참조). 당신이 반대하면 되돌리기에 자유롭게
시스템 전체의 알림 에도이 기능이 필요했습니다. 여기 내 해결책이 있습니다. / proc를 스캔하여 모든 세션 버스를 찾은 다음 각 버스에서 통지 전송을 실행합니다 (버스 당 한 번). 모든 인수는 변경되지 않은 상태로 실제 통지 전송으로 전달됩니다.
#!/bin/bash
/bin/grep -sozZe '^DBUS_SESSION_BUS_ADDRESS=[a-zA-Z0-9:=,/-]*$' /proc/*/environ \
| /usr/bin/php -r '
$busses = array();
array_shift($argv);
while($ln = fgets(STDIN)) {
list($f, $env) = explode("\0", $ln, 2);
if (file_exists($f)) {
$user = fileowner($f);
$busses[$user][trim($env)] = true;
}
}
foreach ($busses as $user => $user_busses) {
foreach ($user_busses as $env => $true) {
if (pcntl_fork()) {
posix_seteuid($user);
$env_array = array("DBUS_SESSION_BUS_ADDRESS" => preg_replace("/^DBUS_SESSION_BUS_ADDRESS=/", "", $env));
pcntl_exec("/usr/bin/notify-send", $argv, $env_array);
}
}
}
' -- "$@"
우분투 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
.
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