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
Related
It works ("klist -A" shows valid principal):
password="<some_pwd>"
user="karim"
department="JUS"
echo $password | kinit $user#$domain.GOV
Password for karim#JUS.GOV:
But with the script I got the error:
Enter Password :Password for karim#JUS.GOV: kinit: Password incorrect while getting initial credentials
*Password for karim#JUS.GOV: kinit: Password incorrect while getting initial credentials
*Password for karim#JUS.GOV: kinit: Password incorrect while getting initial credentials
Each password's letter typing leads to the above message.
Script:
#!/bin/bash
password=""
echo "Provide user: "
read user
echo "Provide department's name (JUS, FIN, MIL): "
read department
pass_var="Provide password:"
while IFS= read -p "$pass_var" -r -s -n letter
do
if [[ $letter == $'\0' ]]
then
break
fi
password=password+"$letter"
pass_var="*"
if [[ $department == JUS ]];then
echo $password | kinit $user#$department.GOV
fi
done
Also, if user specify the department as JUS, FIN or MIL then the kinit command should be executed with the correct set department. I tried something like that but it does not work:
if [[ $department == JUS || FIN || MIL ]];then
Just fixing obvious errors:
#!/bin/bash
password=""
read -p "Provide username: " user
read -p "Provide department's name (JUS, FIN, MIL): " department
pass_var="Provide password: "
while IFS= read -p "$pass_var" -r -s -n 1 letter
do
if [[ $letter == $'\0' ]]
then
break
fi
password="$password$letter"
pass_var="*"
done
echo
if [[ $department == JUS ]]
then
echo "$password" | kinit "$user#$department.GOV"
fi
You can use a case or bash's =~ to match departments:
# ...
if [[ $department =~ JUS|FIN|MIL ]]
then
echo ...
fi
# ...
case "$department" in
JUS|FIN|MIL) echo ... ;;
esac
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
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.
I have been trying to implement a code that makes a predefined user created, be put into a specific groups (first 5 in MyMembers, next 5 in MyGroup, and last 5 to MyMinions), but I always got lost in coding it.
So far this is my code in creating predefined user.
#!/bin/bash
#This script adds a user with a hidden password to your #system.
ans=yes
while [[ "$ans" = yes ]] ;
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 already exists!"
exit 1
else
pass=$(perl -e 'print crypt ($ARGV[0], "password")' $password)
useradd -m -p $pass $username
[ $? -eq 0 ] && echo -e "\nUser has been added to your system!" || echo "\nFailed to add the user!"
fi
else
echo "Only root may add a user to the system"
exit 2
fi
echo -e "\nDo you still want to add more users?. \nType yes to continue adding. \nType yes or any key to exit"
read ans
done
exit
This question already has answers here:
How do I prompt for Yes/No/Cancel input in a Linux shell script?
(37 answers)
Closed 28 days ago.
How do I ask a yes/no type question in Bash?
I ask the question... echo "Do you like pie?"
And receive the answer... read pie
How do I do something if the answer is yes, or starts with y (so yes and yeah, etc, will work too).
I like to use the following function:
function yes_or_no {
while true; do
read -p "$* [y/n]: " yn
case $yn in
[Yy]*) return 0 ;;
[Nn]*) echo "Aborted" ; return 1 ;;
esac
done
}
So in your script you can use like this:
yes_or_no "$message" && do_something
In case the user presses any key other than [yYnN] it will repeat the message.
This works too:
read -e -p "Do you like pie? " choice
[[ "$choice" == [Yy]* ]] && echo "doing something" || echo "that was a no"
Pattern starting with Y or y will be taken as yes.
I like Jahid's oneliner. Here is a slight simplification of it:
[[ "$(read -e -p 'Continue? [y/N]> '; echo $REPLY)" == [Yy]* ]]
Here are some tests:
$ [[ "$(read -e -p 'Continue? [y/N]> '; echo $REPLY)" == [Yy]* ]] && echo Continuing || echo Stopping
Continue? [y/N]> yes
Continuing
$ for test_string in y Y yes YES no ''; do echo "Test String: '$test_string'"; echo $test_string | [[ "$(read -e -p 'Continue? [y/N]>'; echo $REPLY)" == [Yy]* ]] && echo Continuing || echo Stopping; done
Test String: 'y'
Continuing
Test String: 'Y'
Continuing
Test String: 'yes'
Continuing
Test String: 'YES'
Continuing
Test String: 'no'
Stopping
Test String: ''
Stopping
Update
In response to a comment, I'm going to add an adaptation to make this work in zsh.
Disclaimer
I would never write a shell script in zsh even though it is now my primary interactive shell. I still write all scripts in bash or sh. However, since you sometimes need to script modifications to your interactive shell (ex: source ~/dev/set_env), you might want to include prompting.
#! /usr/bin/env zsh
[[ "$(echo -n 'Continue? [y/N]> ' >&2; read; echo $REPLY)" == [Yy]* ]] \
&& echo Continuing \
|| echo Stopping
This works:
echo "Do you like pie?"
read pie
if [[ $pie == y* ]]; then
echo "You do! Awesome."
else
echo "I don't like it much, either."
fi
[[ $pie == y* ]] tests to see of the variable $pie starts with y.
Feel free to make this better if you'd like.
In contrast to the other answers this function gives you the possibility to set a default:
function askYesNo {
QUESTION=$1
DEFAULT=$2
if [ "$DEFAULT" = true ]; then
OPTIONS="[Y/n]"
DEFAULT="y"
else
OPTIONS="[y/N]"
DEFAULT="n"
fi
read -p "$QUESTION $OPTIONS " -n 1 -s -r INPUT
INPUT=${INPUT:-${DEFAULT}}
echo ${INPUT}
if [[ "$INPUT" =~ ^[yY]$ ]]; then
ANSWER=true
else
ANSWER=false
fi
}
askYesNo "Do it?" true
DOIT=$ANSWER
if [ "$DOIT" = true ]; then
< do some stuff >
fi
On the command line you would see
Do it? [Y/n] y
Here is a short function:
prompt(){ read -p "$1" a; return $(test $a = "y"); }
Usage (if the answer is y then do_something executed):
prompt "Do you want it?" && do_something
Usage with multiple commands:
prompt "Do you want it?" && {
do_something1
do_something2
}