2

I am trying to write a shell script that shows all the logged-in users at this moment and if each user has a specific file in one directory. I write a script, but I'm not getting any result! Why is that?

#!/usr/bin/env bash
Files=$( who | cut -d' ' -f1 | sort | uniq)
for file in $FILES
do
if [ -f ~/public_html/pub_key.asc ]; then
    echo "user $file :  Exists"
else
    echo "user $file : Not exists!"
fi
done
3
  • 3
    You have assigned the output from the who command to a variable named 'Files'. You're then trying to read from a variable named 'FILES'. These are different variables, because the shell is case sensitive. Commented Oct 10, 2020 at 5:54
  • 2
    Also, ~/... always refers to the current user's home directory, not the one named by $file. You might want /home/$file/... or something like that. (And $file isn't a file, it's a username, so I'd recommend renaming your variable to better match what they contain.) Commented Oct 10, 2020 at 6:05
  • i tried /home/$file/... that you mentioned and it worked :-) thx Commented Oct 10, 2020 at 9:27

2 Answers 2

4

You need to get each user's home directory. If all of your users have their HOME at /home/$USER, then it's easy:

#!/usr/bin/env bash

who | cut -d' ' -f1 | sort | uniq | 
 while read userName; do
    file="/home/$userName/public_html/pub_key.asc"
    if [ -f $file ]; then
        echo "$file :  Exists"
    else
        echo "$file : Does not exist!"
    fi
done

If you have users whose HOME isn't /home/$USER, such as root for example, then you need to figure out their home directory first. You can do this with getent:

#!/usr/bin/env bash

who | cut -d' ' -f1 | sort | uniq |
while read userName; do
  homeDir=$(getent passwd "$userName" | cut -d: -f6)
  file=public_html/pub_key.asc
    if [[ -f "$homeDir"/"$file" ]]; then
        echo "$file :  Exists"
    else
        echo "$file : Does not exist!"
    fi
done

The next problem is that if you don't have access to the user's HOME, the script will report that the file doesn't exist even if it does. So you could just run it as root, or you could first check if you can access the directory and complain if you don't:

#!/usr/bin/env bash

file="public_html/pub_key.asc"

who | cut -d' ' -f1 | sort | uniq |
while read userName; do
  homeDir=$(getent passwd "$userName" | cut -d: -f6)
  if [ -x $homeDir ]; then
    if [ -f "$homeDir/$file" ]; then
        echo "$file :  Exists"
    else
        echo "$file : Does not exist!"
    fi
   else
     echo "No read access to $homeDir!"
   fi

done
2
  • 1
    You do not need "read" permission on the directory to access a file in it, you need "execute" permission. You should be checking for -x rather than -r on $homeDir Commented Oct 10, 2020 at 15:34
  • 1
    @roaima That's what I tried first, but (at least on my Arch), as a regular user I can't run getent passwd $otherUser, I need root. Hence the eval. And as I was typing that, I tested again and realized that I was using a non-existent user name like an idiot. Sigh. I'll fix, thanks. Commented Oct 10, 2020 at 15:59
1
for I in $(who | cut -d' ' -f1 | sort -u ); do 
    echo -n "user '$I' "; 
    [[ -f ~${I}/public_html/pub_key.asc ]] \
    && echo -n "does " \
    || echo -n "does not "; 
    echo "have a public key: ~${I}/public_html/pub_key.asc"; 
done

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.