3

Okay, so I'm learning Bash, and there's that exercise;

"Write a script that checks every ten seconds if the user 'user000' is logged in."

My idea is to grep a who, but I don't know how to incorporate this into a script. I tried things like

if [ `who | grep "user000"` ] then things

but it returns the matched lines with grep, not true/false.

6 Answers 6

7

You want grep -q. That's "quiet mode"; just sets status based on whether there were any matches, doesn't output anything. So:

if who | grep -q "user000"; then things; fi
Sign up to request clarification or add additional context in comments.

8 Comments

FYI - Solaris's grep does not support -q
DVK: Too bad. POSIX grep specifies `-q' since 1997: opengroup.org/onlinepubs/7990989775/xcu/grep.html Also, drop the brackets. It's the shell equivalent of if (var == true) {}
Probably want to throw a "|cut -d1 -b' '" in there and use "grep '^user000$'". This will avoid false positives when 'user0001' logs in.
Well, I meant drop the brackets and the backticks. The shell will evaluate the exit value of the command transparently.
And then you want to add a ';' before the 'then' or start it on a new line. OR, you can do it in an && list: who | grep -q "user000" && things. (Sorry. I would have just edited your answer if I had the ability)
|
3

You can do

who | grep "user000" > /dev/null  2>&1
# You can use "-q" option of grep instead of redirecting to /dev/null 
# if your grep support it. Mine does not.
if [ "$?" -eq "0" ]
then ...

This uses $? - a Shell variable which stores the return/exit code of the last command that was exected. grep exits with return code "0" on success and non-zero on failure (e.g. no lines found returns "1" ) - a typical arrangement for a Unix command, by the way.

2 Comments

Your redirection >&! creates a file called "!". Perhaps you mean ... 2>&1 > /dev/null
That's cause I used csh refirection instead of sh redirection by force of habit - didn't do anything in bourne in ages :)
2

If you're testing the exit code of a pipe or command in a if or while, you can leave off the square brackets and backticks (you should use $() instead of backticks anyway):

if who | grep "user000" > /dev/null 2>&1
then
  things-to-do
fi

1 Comment

You can also leave off the quotes around user000.
1

Most answers have the right idea, but really you want to drop all output from grep, including errors. Also, a semicolon is required after the ] for an if:

if who | grep 'user000' >/dev/null 2>&1; then
    do things
fi

If you are using GNU grep, you can use the -s and -q options instead:

if who | grep -sq 'user000'; then
    do things
fi

EDIT: dropped brackets; if only needs brackets for comparison ops

3 Comments

You can duplicate file descriptors and shorten the redirection spec.
Semicolon is only required when then appears on the same line. When then is on the following line, it is not needed.
Why do you do the redirection in two times instead of using &>, is there a reason ? (pure curiosity).
0

It's probably not the most elegant incantation, but I tend to use:

if [ `who | grep "user000" | wc -l` = "1" ]; then ....

5 Comments

why not use 'who | grep -c user000' ?
What if the user is logged in more than once?
@Manni: hadn't thought of the -c flag to grep. Is that Posix though, or an extension? @Dennis: does who list one mention per login shell?
I'm ssh'd into a server a couple of time, plus a couple of xterms, plus the gdm login or whatever so my name appears five times in who right now.
@the_mandrill: since -c also works on ancient solaris boxes, I guess it's Posix.
0

To write a Bash script that checks if the user 'user000' is logged in every ten seconds, you can use a loop and the who command combined with grep. The grep command returns a non-zero exit status if the pattern is not found, which you can use to determine if the user is logged in.


# Infinite loop to check every 10 seconds
while true; do
  # Check if user000 is logged in
  if who | grep -q "user000"; then
    echo "user000 is logged in."
  else
    echo "user000 is not logged in."
  fi

  # Wait for 10 seconds before checking again
  sleep 10
done

You can save this script to a file, for example, check.sh, and run it by making it executable and executing it:

chmod +x user.sh
./user.sh

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.