5

Is it possible to write a shell script that enables any user (may not be root) to set a message(e.g. "Download on progress do not turn off" etc.) which will be conveyed like pop-up message (zenity or notify-send) to all other users. If any user is not there at the time of throwing the message they must get it on login or unlocking their screen.

3 Answers 3

1

Nice question. Will give just an half answer... just a seed to see if someone can prepare something starting on this. I have tested this in my system, two users (ubuntu and romano, the two administrators).

I go to a VC and log in as ubuntu --- then I run

sudo sudo -u romano DISPLAY=:0.0 zenity --warning

(the first sudo switch to superuser, the second sudo execute zenity as the user romano)

from a virtual console, the message will appear in "romano" graphical environment.

I suppose that with a bit of mangling the output of w to get the DISPLAY and the users and looping over them it would be possible to have a working solution. Non-graphical connected users can be informed using wall.

I see really difficult to do that without superuser privileges, tough.

1
  • Yes,that will not work on non logged in users. For them I suppose something should be added to system startup files... For example checking the existence of a file and showing its contents. Tricky.
    – Rmano
    Nov 13, 2013 at 5:19
0

If you don't find a direct solution, problems like this can be solved by creating a (simple, in this case) daemon program that runs with elevated privileges and runs when the system starts.

Then, a regular user user can put a file somewhere the daemon will see it or send the daemon a message and the daemon can then do whatever action required elevated privileges.

You just have to be careful what input the daemon accepts so you don't open any security holes in your system.

There is an almost unlimited variety of things that can happen when you pass an unedited character string to a bash script running with elevated privileges! For that reason alone, it would be much better if your daemon were written in a language such as Python where you can do whatever you want to an incoming string before the system gets any chance to interpret/execute its contents.

For users logging in, you can probably add a few lines to /etc/profile which tell the daemon to issue any messages the user needs to see. If you do that, you should probably also do something to avoid unnecessary repetitions when the user logs in again. That's more work, but will keep alerts from turning into nagware.

0

I think what I did is really a bad way to do things. Anyway it works upto a certain level. Any suggestion to improve the script or a better script is always welcome. I tried to do this with the help of the answers given by Rmano and Joe.

I have created a file at /home/message.txt which has permission -rw-rw-rw- so that any user (may not member of sudo gropu) can write their message in it. I have written two scripts both having permissions -rwxr-xr-x

  • /usr/bin/msg_on_login.sh to pass the message to the users on their login
  • /usr/bin/msgpass.sh to pass the message to the users who are on their system (screen may be locked)

msg_on_login.sh

#!/bin/bash

m=`who | grep tty | wc -l`
# how many users are logged in
num=`expr $m - 1`
# it helps to send the message to exact display in case one or more user is already logged in
if [ `wc -w /home/message.txt| gawk '{print $1}'` -gt 1 ] && [ $num -gt 0 ]
    then
        DISPLAY=:$num.0 zenity --info --text="`cat /home/message.txt`" &
    elif [ `wc -w /home/message.txt| gawk '{print $1}'` -gt 1 ]
        then  
            zenity --info --text="`cat /home/message.txt`" &
    else
        exit 0
fi

and add this line "/usr/bin/msg_on_login.sh" at the end of /etc/profile and change permission of /usr/bin/msg_on_login.sh to -rwxr-xr-x. Then the script will run each time any user login and he will get the message.

msgpass.sh

#!/bin/bash
m=`who | grep tty | awk '{print $1}' | sort | uniq | wc -l`
min=0
max=`expr $m - 1`
array=(`who | grep tty | awk '{print $1}'`)
for num in `seq $min $max`
do
if [ `wc -w /home/message.txt| gawk '{print $1}'` -gt 1 ] 
then
    sudo sudo -u ${array[num]} DISPLAY=:$num.0 zenity --info --text="`cat /home/message.txt`" &
else
    exit 0
fi
done
echo 0 > /home/message.txt

change permission of /usr/bin/msgpass.sh to -rwxr-xr-x.

Cons

  • If any user login from a virtual terminal he will get an error message. To handle that situation is tricky. As such a situation was not intended so I skipped that part.
  • Say 1st user (who loged in before 2nd user) logout the system then msgpass.sh stumbles over and gives error.
  • To run msgpass.sh you need to have member of sudo group.
  • I am also finding a way to run the script as non-root user.

Note

  • Need help to remove first two cons.
1
  • For the first con: you can probably check if the variable $DISPLAY exists and is set --- if not, you are not in a graphic session. Something on the line of [ x$DISPLAY = x ] && exit or something similar...
    – Rmano
    Nov 25, 2013 at 22:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .