For each parameters, script checks if there exists a user of such username. If exists script prints all processes run by this user - linux

#!/bin/bash
if [ $# -ne 1 ]
then
echo "Script Should Have Atleast 1 Parameter"
exit
fi
USER=$1
echo $USER
if [ $? -eq 0 ]
then
echo " Yes the User Exists"
else
echo "No , The User Doesnt Exists"
fi
My problem here is whatever the input i give, it shows yes the user exists.
And can anyone suggest me a command to print out all the process runs by this user
Should i use awk , or grep

Well, first of all, you are not checking if user exists, but ultimately if command echo $USER didn't fail. You will need to implement proper user check.
Good way how to check if arbitrary user exists would be something like this, using command id.
if id "${1}" &> /dev/null; then
echo 'user found'
else
echo 'user not found'
fi
Next you want to list all processes belonging to this user. You will need ps. There are many ways how ps can format output. Be sure to check manual page of ps. Here is example which lists command and pid of all processes belonging to user in "$1".
ps -eo pid,comm --user $(id -u "${1}")
At last, running check using id and only then using ps for process list is inefficient at least. In your use-case, you can simply run ps and check if it was successful. If not, you can show warning that user was not found.
#!/bin/bash
if ! ps -u "$1" 2> /dev/null; then
echo 'user not exists!'
exit 1
fi

Related

if with exit 0 & 1 and showing process

I want to solve a certain task with a bash script which I pass to a parameter, but unfortunately I don't get anywhere.
This is what it is about.
If a user exists, the exit status 0 should be returned and displayed. If this user does not exist then 1. This works fine so far. Now it is so that if the user should exist and has running processes, only the processes should be displayed. Otherwise only the exit status 0 if the user exists and has no running processes.
#!/bin/bash
user=$1
exists=$(grep -c $user /etc/passwd)
if [ "$exists" -ne 0 ]; then
echo $?
else
echo $?
fi
I added an additional elif, but that did not work. How can I customize the script to show me the running processes for an existing user if they should exist or if no running processes exist but the user exists only returns and displays the status 0 or 1?
Thanks a lot!
The id command can tell if user exists, without need to tap the passwd file, and works regardless of what resource type is providing the users database to the system.
#!/bin/sh
if id --user "$1" > /dev/null 2>&1;
then
ps --user "$1" --format pid=,comm= || :
else
false
fi
Or a one-liner:
sh -c 'id -u "$1">/dev/null 2>&1&&{ ps -u "$1" -o pid=,comm=||:;}' sh username
grep returns the exit status you are looking for, so you probably just want:
#!/bin/bash
user=$1
if grep -q "$user" /etc/passwd; then
echo 0;
exit 0;
else
echo 1;
exit 1;
fi
But that's quite redundant and could be more easily written:
grep -q "$user" /etc/passwd
rv=$?
echo "$rv"
exit "$rv"
However, the requirement to print the return status is odd, and if you simply drop that, your script can just be the grep.
Note that this completely disregards that fact that grepping /etc/password for the user name is not an adequate test to determine if the user exists, but that does not seem to be the heart of this question.

How to fix "id -u" returning 0 into my variable for if statement?

I'm trying to put the result of "id -u $1" into a variable in order to verify it with an if statement but it seems like it's returning 0 into my variable even tho I've checked it and it's supposed to be 1008.Is it because the username is taken from the argument of the script?
UID=`id -u $1`
LOCK=`usermod -L $1`
if test $UID -lt 500;then
echo "impossible to lock user"
else
$LOCK;
fi
Your problem is that you use system variable in your script and try to change it.
instead of UID try to use UID1 (for example) as variable name. And your script will be something like:
UID1=`id -u $1`
LOCK=`usermod -L $1`
if test $UID1 -lt 500;then
echo "impossible to lock user"
else
$LOCK;
fi

ssh to different nodes using shell scripting

I am using below code to ssh to different nodes and find if an user exists or not. If the user doesn't exist it will create it.
The script works fine if I don't do ssh but it fails if I do ssh.
How can I go through different nodes using this script?
for node in `nodes.txt`
usr=root
ssh $usr#$node
do
if [ $(id -u) -eq 0 ]; then
read -p "Enter username : " username
read -s -p "Enter password : " password
egrep "^$username" /etc/passwd >/dev/null
if [ $? -eq 0 ]; then
echo "$username exists!"
exit 1
else
pass=$(perl -e 'print crypt($ARGV[0], "password")' $password)
useradd -m -p $pass $username
[ $? -eq 0 ] && echo "User has been added to system!" || echo "F
ailed to add a user!"
fi
else
echo "Only root may add a user to the system"
exit 2
fi
done
Your script has grave syntax errors. I guess the for loop at the beginning is what you attempted to add but you totally broke the script in the process.
The syntax for looping over lines in a file is
while read -r line; do
.... # loop over "$line"
done <nodes.txt
(or marginally for line in $(cat nodes.txt); do ... but this has multiple issues; see http://mywiki.wooledge.org/DontReadLinesWithFor for details).
If the intent is to actually run the remainder of the script in the ssh you need to pass it to the ssh command. Something like this:
while read -r node; do
read -p "Enter user name: " username
read -p -s "Enter password: "
ssh root#"$node" "
# Note addition of -q option and trailing :
egrep -q '^$username:' /etc/passwd ||
useradd -m -p \"\$(perl -e 'print crypt(\$ARGV[0], \"password\")' \"$password\")" '$username'" </dev/null
done <nodes.txt
Granted, the command you pass to ssh can be arbitrarily complex, but you will want to avoid doing interactive I/O inside a root-privileged remote script, and generally make sure the remote command is as quiet and robust as possible.
The anti-pattern command; if [ $? -eq 0 ]; then ... is clumsy but very common. The purpose of if is to run a command and examine its result code, so this is better and more idiomatically written if command; then ... (which can be even more succinctly written command && ... or ! command || ... if you only need the then or the else part, respectively, of the full long-hand if/then/else structure).
Maybe you should only do the remote tasks via ssh. All the rest runs local.
ssh $user#$node egrep "^$username" /etc/passwd >/dev/null
and
ssh $user#$node useradd -m -p $pass $username
It might also be better to ask for username and password outside of the loop if you want to create the same user on all nodes.

Unable to get bash if condiftion to work with multiple commands per outcome

I have been trying to get various versions of this to work:
[[ -e "~/usersl" ]] && { user=`cat ~/usersl`; echo Username: $user; } || { read -p "Username:" user; echo $user > ~/usersl; }
The main goal is to have a if..then..else all in one line. From what I have read on this site and others, this should work. It should check to see if the usersl file exists and if it does then it prints out the detected username and populates the $user variable. If the usersl file doesn't exist then it should ask for the username and populate the variable at the same time then record the new username into a file. Once that has been done the next tiem the command is ran the file already exists and it just displays the username and propagates the variable. Hope my explanation isn't overly complicated but the task is very simple.
Any help is much appreciated
Your most immediate bug had nothing to do with the conditional syntax, but was caused by a bug in how you were quoting around your test:
if [[ -e ~/usersl ]]; then
user=$(<~/usersl)
echo "Username: $user"
else
read -p "Username:" user
echo "$user" > ~/usersl
fi
As a one-liner, this would be:
if [[ -e ~/usersl ]]; then user=$(<~/usersl); echo "Username: $user"; else read -p "Username:" user; echo "$user" >~/usersl; fi
Tilde expansion is suppressed by quotes. If in doubt, write $HOME instead of ~.
Using a && b || c is bug-prone: If a succeeds and b tries to run but fails, you can have c run even though b was also invoked.

How do I search for a certain piece of text inside of a variable?

I am working on a script which prompts the user for their username. Once entered, the script uses the 'rwho' command to get a list of users who are logged into the network. It should crosscheck the text they entered (their username) with the results from the rwho command.
If a match is found then it displays a message saying so, if not then it also makes the user aware of this.
Here is the script and my attempt so far:
#!/bin/sh
#
# User network checking script
#
# Using rwho command to get user list
OUTPUT="$(rwho)"
echo "${OUTPUT}"
# Prompt for username
echo "Please enter your username: "
read username
# Input validation
if [ -z "$username"]
then
echo "No username supplied"
echo "Please enter your username: "
read username
fi
# Search for user
if `echo ${OUTPUT} | grep "${username}" 1>/dev/null 2>&1'
then
echo "$username is logged in."
else
echo "$username is not present."
fi
I consistently get errors with the Search for User part. I don't have outstanding knowledge of Linux so if anyone could fix this and help me I would be greatly appreciative.
Your usage of quotes is weird.
if echo "$OUTPUT" | grep -q "$username"
should work.
-q makes grep quiet (and is shorter than your redirections).

Resources