সমস্ত চলমান এক্স প্রদর্শনগুলিতে একটি বিজ্ঞপ্তি দেখান


16

কমান্ড লাইনটি ব্যবহার করে, আমি প্রতিটি চলমান এক্স ডিসপ্লেতে একটি বিজ্ঞপ্তি প্রদর্শন করতে চাই। (এবং চলমান কনসোল)

কিছুটা এইরকম:

notify-send-all 'Warning' 'Nuclear launch in 5 minutes, please evacuate'

এমন কোন প্রোগ্রাম আছে যা এটি করবে? যদি তা না হয় তবে এটি কি বাশ দিয়ে বাস্তবায়ন করা যেতে পারে?


1
বহু বছর পরে এখানে আসার লোকদের জন্য, এই উত্তরে একটি সাধারণ বিজ্ঞপ্তি_ল ফাংশন রয়েছে যা উবুন্টু 16.04 এ কাজ করে এবং মূল দ্বারা শুরু হওয়া স্ক্রিপ্টগুলিতে ব্যবহার করা যেতে পারে।
mivk

উত্তর:


16

আপনি কমান্ড ওয়াল সহ সমস্ত কনসোলগুলিতে একটি বার্তা প্রেরণ করতে পারেন।

এক্স এর অধীনে বিজ্ঞপ্তি প্রেরণের জন্য বিজ্ঞপ্তি-প্রেরণ রয়েছে যা বর্তমান ব্যবহারকারীর বর্তমান প্রদর্শনীতে একটি বিজ্ঞপ্তি প্রেরণ করে। (আপনার প্রশ্ন থেকে, আমি অনুমান করি যে আপনি এটি ইতিমধ্যে জানেন)) আপনি কিছু বাশ স্ক্রিপ্টিং দিয়ে এটি তৈরি করতে পারেন। মূলত আপনাকে খুঁজে বার করতে হবে কোন ব্যবহারকারী কোন এক্স-ডিসপ্লেতে থাকে। একবার আপনি এই তথ্যটি পেয়ে গেলে আপনি এই জাতীয় বিজ্ঞপ্তি-প্রেরণ ব্যবহার করতে পারেন:

DISPLAY=:0 sudo -u fschmitt notify-send "Message"

যেখানে fschmitt 0 প্রদর্শনকারীর ব্যবহারকারী। আপনি সমস্ত ব্যবহারকারী এবং তাদের প্রদর্শনগুলি খুঁজে পেতে "কারা" কমান্ডের আউটপুট পার্স করতে পারেন। আউটপুট এই মত দেখাচ্ছে

[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)

আপনি দেখতে পাচ্ছেন, দুটি ব্যবহারকারী এক্স সেশন চালাচ্ছেন, ডিসপ্লে 0 তে মার্কমার্ক 3 এবং প্রদর্শনীতে 1 টি সিমনকি 1 I -9।] *) কনসোল লগইনগুলি থেকে মুক্তি পেতে এবং প্রথম বন্ধনীগুলির মধ্যে স্ট্রিং থেকে ডিসপ্লে আইডিটি বের করতে।


2
কমান্ডটি whoআপনাকে জানায় যে লগ ইন হয়েছে এবং এক্সটি প্রদর্শন করে যে লগইন রয়েছে। আপনি এটি কিছুটা ফিল্টার করতে পারে।
tante

1
শেল স্ক্রিপ্টে কেবলমাত্র একটি লুপ ব্যবহার করা ভাল তবে আপনি সর্বদা এর মতো কিছু করতে পারেন who | awk '/\(:[0-9]+\)/ {gsub("[:|(|)]","");print "DISPLAY=:"$5 " sudo -u " $1 " notify-send \"Message\""}' | bash। এছাড়াও, আপনি ইউনিক্স.স্ট্যাকেক্সেঞ্জার.কম
স্টিভেন ডি

8

এই থ্রেডটি কিছুটা পুরানো, দুঃখিত, তবে আমি আশা করি যে আমি এখনও বিষয়টিতে দরকারী কিছু যুক্ত করতে পারি। (এছাড়াও জোসেফ কুফনার একটি দুর্দান্ত স্ক্রিপ্ট লিখেছিলেন, এটি আমার স্বাদের জন্য কিছুটা দীর্ঘ ছিল এবং এটি পিএইচপি ব্যবহার করে)

মূল প্রশ্নে বর্ণিত হিসাবে আমারও একটি সরঞ্জামের প্রয়োজন ছিল (সমস্ত সক্রিয় এক্স-ব্যবহারকারীদের জন্য একটি বার্তা প্রেরণে)। এবং এখানে থাকা উত্তরের ভিত্তিতে আমি এই ছোট্ট বাশ-কেবল স্ক্রিপ্টটি লিখেছি, যা সক্রিয় এক্স-ব্যবহারকারীদের জন্য অনুসন্ধান করে ('কে' ব্যবহার করে) এবং তারপরে প্রতিটি সক্রিয় ব্যবহারকারীর জন্য বিজ্ঞপ্তি-প্রেরণ চালায়।

এবং সর্বোত্তম: আপনি আমার স্ক্রিপ্টটি তার সমস্ত পরামিতি সহ "" বিজ্ঞপ্তি-পাঠান "এর মতো ব্যবহার করতে পারেন! ;-)

অবহিত প্রেরণ সব:

#!/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

উপরের কোডটি "বিজ্ঞপ্তি-পাঠান-সমস্ত" নামের একটি ফাইলে অনুলিপি করুন, সম্পাদনযোগ্য করে তুলুন এবং এটি / usr / স্থানীয় / বিন বা / usr / বিনকে (আপনার পছন্দ মতো) অনুলিপি করুন । তারপরে এটি চালান যেমন একটি কনসোল সেশনে মূল হিসাবে:

notify-send-all -t 10000 "Warning" "The hovercraft is full of eels!"

আমি এখন বেশ কয়েক মাস এটি বিভিন্ন মেশিনে ব্যবহার করছি এবং এখনও পর্যন্ত কোনও সমস্যা হয়নি এবং আমি মেট এবং দারচিনি ডেস্কটপগুলি দিয়ে এটি পরীক্ষা করেছি। ক্রোন এবং অ্যানাক্রনের মধ্যে এটি সফলভাবে চালাও।

আমি এই স্ক্রিপ্টটি আর্চলিনাক্সের জন্য / এর অধীনে লিখেছি, সুতরাং দয়া করে আমাকে বলুন যদি আপনার অন্য কোনও লিনাক্স বিতরণ বা ডেস্কটপগুলিতে সমস্যা হয়।


|egrep?? একটি কমান্ড egrep হয়?
Sw0ut

@ Sw0ut, egrep আসলে একটি কমান্ড। তবে গ্রেপ (1) এর ম্যান পেজে বলা হয়েছে যে egrep, fgrep এবং rgrep হ্রাস করা হয় এবং তাদের সমতুল্য ফর্ম "গ্রেপ-ই", "গ্রেপ-এফ" এবং "গ্রেপ-আর" ব্যবহারের পরামর্শ দেওয়া হয়।
rsuarez

পরিবর্তে awk '{print $1$5}'এটি ব্যবহার করা ভাল awk '{print $1$NF}', যাতে এটি কিছু লোকেলগুলিতে বিরতি না দেয় যেখানে তারিখ ফাঁকা ফাঁকা থাকে (যেমন Jun 3পরিবর্তে 2017-06-03) eg সমস্ত ব্যবহারকারীর পরিবর্তে নির্দিষ্ট ব্যবহারকারীকে অবহিত করার জন্যও এখানে একটি সংস্করণ দেওয়া আছে: gist.github.com/shvchk/ba2f0da49bf2f571d6bf606d96f289d7
শেভচুক

1
পথে ব্যবহার grep -Eএবং সংযোজন /binকরার পরে উবুন্টুতে দুর্দান্তভাবে কাজ করে (সম্পাদনা দেখুন)। আপনি যদি আপত্তি করেন তবে
ফিরতে

3

কিছু সিস্টেম-ব্যাপী বিজ্ঞপ্তির জন্যও আমার এটি দরকার ছিল। এখানে আমার সমাধান। এটি সমস্ত সেশন বাসগুলি সন্ধান / স্ক্যান করে এবং তারপরে এটি প্রতিটিটির প্রতি বিজ্ঞপ্তি-প্রেরণ কার্যকর করে (একবার প্রতি বাসে)। সমস্ত আর্গুমেন্ট বাস্তব বিজ্ঞপ্তি-প্রেরণে অপরিবর্তিত পাস করা হয় passed

#!/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);
                        }
                }
        }
' -- "$@"

1

উবুন্টু ১.0.০৪-এ, আমি ক্রন্টব থেকে মূল হিসাবে চলমান স্ক্রিপ্টের বিজ্ঞপ্তি চেয়েছিলাম। এনভায়রনমেন্ট ভেরিয়েবল সেট করার পরে, 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 ভেরিয়েবলটি পাওয়া যায় তা সম্ভবত আপনার বিতরণের উপর নির্ভর করে। উবুন্টু ১.0.০৪-তে, এটি রয়েছে /run/user/$UID/dbus-session, যা কেবল সোর্স করা যায়। id -uউপরের ফাংশনে ব্যবহৃত ইউজারনেম থেকে ইউআইডি পাওয়ার জন্য ব্যবহৃত হয় who


এটি কিভাবে ব্যবহার করতে? আপনি কি আমাকে সাহায্য করতে পারেন?
এলগোলোনড্রিনো

0

এখানে অ্যান্ডির স্ক্রিপ্টের একটি আপডেট রয়েছে: এটি যেভাবে নির্ধারণ করেছে সেটি DBUS_SESSION_BUS_ADDRESSসেন্টোস 7-এ কাজ করে না Also এছাড়াও whoকমান্ডটি কোনও কারণে কিছু সেশন তালিকাভুক্ত করে না, সুতরাং আমি তার ps auxপরিবর্তে আউটপুট পার্স করব । এই স্ক্রিপ্টটি ধরে নিয়েছে যে ব্যবহারকারীরা এক্স 2জিও ( 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

-1
users=$(who | awk '{print $1}')

for user in $users<br>
do
        DISPLAY=:0 sudo -u $user notify-send "hello!!"
done
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.