This is a request for improvement and update (NOT a duplicate!) on these 2 questions & answers:

I'm currently on Ubuntu 15.04 and the command who gives an output like this when run in a root terminal, as my script will be used as a cron job:

sadi     :0           2015-10-07 17:32 (:0)
root     pts/0        2015-10-07 19:55 (:0)

After studying the questions & answers mentioned above, I wrote these (a little updated, but unfinished) lines:

xuser=${who | grep -m1 ^.*\) | awk '{print $1}'}
xdisplay=${who | grep -m1 ^.*\) | awk '{print $5}' | sed 's/[(|)]//g'}
DISPLAY="$xdisplay" XAUTHORITY=/home/"$xuser"/.Xauthority su "$xuser" -c "notify-send 'Message'"

I wonder why these 2 variables don't work (giving bad substitution)... Also, in order to make this script applicable to different (e.g. multi-user) configurations, I think I should take into account that there might be other users as well. So I guess I then need to create a loop that will input each user and their X display to the last command, but as a beginner in bash scripting I don't know how...

Until I find an answer to this question I'm using a single-user script like this:

DISPLAY=:0 XAUTHORITY=/home/"$cuser"/.Xauthority su "$cuser" -c "notify-send 'Message'"

It seems the grep option -m1 should also be modified (as well as replacing ${...} with $(...)) as it merely defines how many lines should be captured from the top of the output.

The command who - run in a root terminal again - gives an output like this when there is also a guest session, i.e. multi-user environment:

sadi     :0           2015-10-08 10:40 (:0)
guest-bAMpqo :1           2015-10-08 12:22 (:1)
root     pts/28       2015-10-08 12:43 (:0)
guest-bAMpqo pts/18       2015-10-08 12:25 (:1)

So this should give me a list of names of X users and X Displays:

xusers=$(who | grep ' :[0-9]' | awk '{print $1}')
xdisplays=$(who | grep ' :[0-9]' | awk '{print $5}' | sed 's/[(|)]//g')
DISPLAY="$xdisplay" XAUTHORITY=/home/"$xuser"/.Xauthority su "$xuser" -c "notify-send 'Message'"

Now I need to modify the last command to capture that list line by line.

  • 1
    You need to tell us what happens when you run your custom script, i.e. copy&paste the stdout (and stderr) of an actual run.What do you mean by not working variables? Variables in bash work just fine. However, you are not setting them correctly. I am pretty sure you meant to write $(...) instead of ${...} in your first 2 lines. Both exist in bash. However , they do very different things. Bash should actually tell you bad substitution.
    – Bananguin
    Oct 8, 2015 at 9:08
  • @Bananguin Thank you very much! The variables are working now when I replace ${...} with $(...) All I need now to make this work for all X users and their X displays.
    – Sadi
    Oct 8, 2015 at 9:19
  • 1
    @Sadi - it would work in ksh. The ${ command sub ;} form is specific to ksh93.
    – mikeserv
    Oct 8, 2015 at 10:11

1 Answer 1


Finally, I've found the answer by myself searching in this invaluable knowledge database of StackExchange Unix & Linux!!!

In addition to the answers to the questions above, I've also used the accepted answer to this question: Read two text files, concatenate each line

And here is the answer to my question above:

xuser=$(who | grep ' \:[0-9]' | awk '{print $1}')
xdisplay=$(who | grep ' \:[0-9]' | awk '{print $5}' | sed 's/[(|)]//g')
echo "$xuser" > /tmp/xusers.txt
echo "$xdisplay" > /tmp/xdisplays.txt
while read -r -u3 xuser; read -r -u4 xdisplay; do
    DISPLAY="$xdisplay" XAUTHORITY=/home/"$xuser"/.Xauthority su "$xuser" -c "notify-send 'Message multi-user'"
done 3</tmp/xusers.txt 4</tmp/xdisplays.txt

You must log in to answer this question.

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