Reputation: 27
I posted earlier with something similar to this. I am trying to check if a user is online with the command $ ./user mburkhar
which prints out mburkhar is logged on
. My program works correctly but if I just type $ ./user mb
is also states mb is logged on
. What I have is fine, but is there a way to match what the user typed in exactly instead of slightly matching the first 2 characters..?
Here is my program so you can see what I did:
# Check if a user is logged on
if [ -z $1 ] ; then
read user
else
user=$1
fi
if [ `who | cut -d" " -f1 | grep $1` ] ; then
echo "$1 is logged on"
else
echo "$1 is either not valid or logged on"
fi
Upvotes: 1
Views: 75
Reputation: 438398
To complement the accepted answer:
-w
works well and is widely supported (GNU Grep, BSD Grep), but it is not POSIX-compliant.
In your case, given that your output lines contain just a username each and nothing else, using -x
- to match entire lines - would make sense too (and it is POSIX-compliant).
Also, since you're searching for a literal username, it's good practice to use grep
's -F
option to indicate just that.
Using [ $(...) ]
(or [ `...` ]
) to test for nonempty output from a command is somewhat fragile and inefficient; it's better and simpler to:
and suppress stdout output, if needed
grep
's -q
option not only suppresses stdout, but also makes the search potentially more efficient by terminating once the first match is found (with exit code 0
to indicate success):
if who | cut -d' ' -f1 | grep -Fxq "$1"; then # ...
Similarly, [ -z $1 ]
is fragile in that would break if an argument with embedded whitespace is passed - not likely in this case, but it's better to get in the habit of using [[ -z $1 ]]
(or, if you must remain POSIX-compliant, [ -z "$1" ]
).
Outside of [[ ... ]]
, it makes sense to habitually double-quote variable references, such as the $1
in the grep
command.
If we put it all together:
# Check if a user is logged on
if [[ -z $1 ]]; then
read user
else
user=$1
fi
if who | cut -d' ' -f1 | grep -Fxq "$1"; then
echo "$1 is logged on"
else
echo "$1 is either not valid or logged on"
fi
Upvotes: 1
Reputation: 19204
Specify the start and end of string anchors like this:
if [ -z $1 ] ; then
read user
else
user="^$1$"
fi
if [ $(who | cut -d" " -f1 | grep $user | uniq ) ] ; then
echo "$1 is logged on"
else
echo "$1 is either not valid or logged on"
fi
I also added the uniq
to remove duplicate matches, in case an user got more than one tty, or [
will exit with: [: too many arguments
Upvotes: 0
Reputation: 106047
You can use grep's -w
(--word-regexp
) option to match only entire words. Replacing grep $1
with grep -w $1
in your script should fix it.
Upvotes: 0