I am trying to write a program where the user can enter a username and password, then the code should check if the username and password are correct unfortunately whenever it checks no matter if the username/password is correct of not it will echo "Username Verified".
#!/bin/bash
echo "Username"
read username
echo "Password"
read password
sleep 1
correct_u=user
correct_p=pass
if [[ $username -eq $correct_u ]]
then
echo "Username Verified..."
else
echo "Username Incorect..."
fi
sleep 1
if [[ $correct_p -eq $password ]]
then
sleep 1
echo "Password Verified..."
else
echo "Password Incorect..."
fi
I have tired checking that all the variables work
Unless username and correct_u consist solely of digits, [[ $username -eq $correct_u ]] will always evaluate to true, since -eq forces the arguments to be numbers, and if there are no number, the arguments are treated as zero.
To do a string comparision, do
[[ $username == "$correct_u" ]]
Quoting the right-hand side is important here, to avoid that it is interpreted as glob-pattern, since == in general does a wildcard match.
You should use = instead of -eq when comparing strings in bash. = is used for string comparison while -eq is used for integer comparison:
#!/bin/bash
echo "Username"
read username
echo "Password"
read password
sleep 1
correct_u=user
correct_p=pass
if [[ "$username" = "$correct_u" ]]
then
echo "Username Verified..."
else
echo "Username Incorrect..."
fi
sleep 1
if [[ "$correct_p" = "$password" ]]
then
sleep 1
echo "Password Verified..."
else
echo "Password Incorrect..."
fi
Embedding your name & pw in cleartext in the file isn't ideal. The user ID must be able to read it to execute the commands in it; executable permissions won't help if you take away read.
Use that to your advantage. Set the user/group/world permissions appropriately. Then the user and password are entered at login...
You might want to combine methods from here and here, reading the right password securely from a vault file and comparing that to the one you read silently from the user.
But first, as already mentioned - fix your test.
$: [[ "one" -eq "two" ]] && echo same || echo no
same
$: [[ "one" == "two" ]] && echo same || echo no
no
$: [[ "one" == "one" ]] && echo same || echo no
same
Related
I am writing shell script which will validate entered password which should not accept ! $ & sign in password. I need to throw error messages. Kindly help me here.
Here problem occurring when I give password like yt!$&
It is not throwing me error messages
echo "enter password which do not include ! $ & sign"
read -s password
if [[ $password != *"&"* || $password != *"!"* || $password != *"$"* ]];
then
echo "Do not enter ! $ & in password" else
echo $password
fi
x!=a || x!=b || x!=c is equivalent to !(x==a && x==b && x==c).
This is only true when none of the three conditions match.
However, I guess you wish to fail if even a single condition matches.
For that you should use: !(x==a || x==b || x==c).
Or equivalently: x!=a && x!=b && x!=c
After that, it should be clear that you also need to invert the test.
You can combine the tests and shorten to:
if [[ $password == *[\&!$]* ]]; then
echo "Do not enter ! $ & in password"
else
echo $password
fi
(& has to be escaped.)
You just need to fix your condition:
if [[ $password == *"&"* || $password == *"!"* || $password == *"$"* ]]; then
echo "Do not enter ! $ & in password"
fi
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;
Is there a shortcut (ie all on one line) for doing the following?
if [ -z "$PASSWORD" ] ; then
echo "PASSWORD envvar required. Exiting..."
exit 1
fi
I'm thinking along the lines of the following. Or maybe there's an even shorter way.
[ -z "$PASSWORD" ] && ...
That is, how do put the echo then exit after the &&
You can do it like this:
[ -z "$PASSWORD" ] && { echo "PASSWORD envvar required. Exiting..."; exit 1; }
Note the extra ; at the end of the line before the }, this is necessary and you cannot leave it out.
It's called a command group.
[[ -z "$PASSWORD" ]] && echo "PASSWORD envvar required. Exiting." && exit 1
Your single brackets will work fine. Consider learning to use the doubles, though.
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;
I have a password function that I borrowed from How do I echo stars (*) when reading password with read?
I tried to adapt it so that I can run through the function twice to do a password confirmation and then evaluate the 2 passwords to determine if they match but I seem to be missing some basics of how bash works in this case.
I tried replacing PASSWORD with $1 but kept getting command not found errors
passWord() {
unset PASSWORD
unset CHARCOUNT
stty -echo
CHARCOUNT=0
while IFS= read -p "$PROMPT" -r -s -n 1 CHAR; do
# Enter - accept password
if [[ $CHAR == $'\0' ]] ; then
break
fi
# Backspace
if [[ $CHAR == $'\177' ]] ; then
if [ $CHARCOUNT -gt 0 ] ; then
CHARCOUNT=$((CHARCOUNT-1))
PROMPT=$'\b \b'
PASSWORD="${PASSWORD%?}"
else
PROMPT=''
fi
else
CHARCOUNT=$((CHARCOUNT+1))
PROMPT='*'
PASSWORD+="$CHAR"
fi
done
stty echo; echo
${1}=${PASSWORD}
}
echo -n "Enter the password > "
passWord passOne
echo -n "Please re-enter the password > "
passWord passTwo
if [[ $passOne == $passTwo ]]; then
PASSWORD=$passOne
else
echo "Passwords did not match, please try again."
fi
Update
Here is the script with the latest updates
#!/bin/bash
passWord() {
unset password
local prompt char
stty -echo
charcount=0
while IFS= read -p "$prompt" -r -s -n 1 CHAR; do
# Enter - accept password
if [[ $char == $'\0' ]] ; then
break
fi
# Backspace
if [[ $char == $'\177' ]] ; then
if [ $charcount -gt 0 ] ; then
charcount=$((CHARCOUNT-1))
prompt=$'\b \b'
password="${password%?}"
else
prompt=''
fi
else
charcount=$((charcount+1))
prompt='*'
password+="$char"
fi
done
stty echo; echo
}
echo -n "Enter the password > "
passWord
pass1=$password
echo -n "Please re-enter the password > "
passWord
pass2=$password
if [[ "$pass1" == "$pass2" ]]; then
PassWord=$pass1
else
echo "Passwords did not match, please try again."
fi
You are missing a declaration of your shell.
Please add a shebang as the first line:
#!/bin/bash
The assignment of variables (the line ${1}=${PASSWORD}) doesn't work.
One way to solve it (not recomended) is to add eval:
eval "${1}=${PASSWORD}" # don't use quite risky.
But as that makes any input a security issue, you should use some other line.
One solution is to use declare (bash 4.2+):
declare -g "${1}=${PASSWORD}"
The -g is required (required and available since bash 4.2) to change General variables (not local to the function).
Or use printf (since bash 3.1):
printf -v "${1}" '%s' "${PASSWORD}"
Other than that, you should add a local command for variables used inside the function to avoid conflicts with external variables and should add a PROMPT='' just before the loop to avoid the printing of an initial asterisk when calling the function a second time.
It should be said that using variables in CAPS should be avoided. Variables in CAPS denote environment variables, the rest of variables use lower case to avoid conflicts.