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

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

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.

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

#!/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

Repeat command in linux script if there is an error for google cloud console tools [duplicate]

I have a script and want to ask the user for some information, but the script cannot continue until the user fills in this information. The following is my attempt at putting a command into a loop to achieve this but it doesn't work for some reason:
echo "Please change password"
while passwd
do
echo "Try again"
done
I have tried many variations of the while loop:
while `passwd`
while [[ "`passwd`" -gt 0 ]]
while [ `passwd` -ne 0 ]]
# ... And much more
But I can't seem to get it to work.
until passwd
do
echo "Try again"
done
or
while ! passwd
do
echo "Try again"
done
To elaborate on #Marc B's answer,
$ passwd
$ while [ $? -ne 0 ]; do !!; done
Is nice way of doing the same thing that's not command specific.
You need to test $? instead, which is the exit status of the previous command. passwd exits with 0 if everything worked ok, and non-zero if the passwd change failed (wrong password, password mismatch, etc...)
passwd
while [ $? -ne 0 ]; do
passwd
done
With your backtick version, you're comparing passwd's output, which would be stuff like Enter password and confirm password and the like.
If anyone looking to have retry limit:
max_retry=5
counter=0
until $command
do
sleep 1
[[ counter -eq $max_retry ]] && echo "Failed!" && exit 1
echo "Trying again. Try #$counter"
((counter++))
done
You can use an infinite loop to achieve this:
while true
do
read -p "Enter password" passwd
case "$passwd" in
<some good condition> ) break;;
esac
done
while [ -n $(passwd) ]; do
echo "Try again";
done;

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.

Resources