I have a program that asks input from user on their username and password then stores it in a text file column one is usernames and column 2 is passwords, i need a command that replaces the password when the user inputs their username and new password, heres what i have
#!/bin/bash
#admin menu
#Register User
echo enter the username of the user you want to register.
read reguser
echo enter the password of the user you want to register.
read regpass
User_Pass="username_pass.txt"
if [ ! -e "$User_Pass" ];
then
echo "Creating Username and Passwords file"
touch $User_Pass
fi
echo "$reguser $regpass" | cat >> $User_Pass
echo user succesfully registered.
#Change Password
echo "Enter the username you want to change the password for"
read change1
change2=$(grep -q $change1 username_pass.txt)
if [ $change2=0 ];
then
echo enter your new password
read newpass
awk -v newpass="$newpass" -v change1="$change1" '$1 ~ change1 {$2 = newpass}' username_pass.txt
#i tried this but it didnt work
echo "password changed!"
else
echo "no such username."
fi
You can use sed
sed -i "s/$change1.*/$change1 $newpass/" username_pass
Related
I have a simple CLI tool asking for a master password, and printing a string $USER $PASSWORD only if the master password is correct.
How to reproduce?
Here is a script just for demonstrating my use-case, the real script is in fact a CLI tool on which I have no control:
#!/usr/bin/env sh
printf "Enter master password: "
read -s password
echo
[ "$password" == "MasterPassword" ] && echo "user1 Passw0rd!"
Example of usage:
$ ./my-cli-tool
Enter master password: ********
user1 Passw0rd!
Issue
I don't want the password (Passw0rd!) to be printed on screen. I want to print only the user (user1), and just copy the password (Passw0rd!) to the clipboard (let's say with xclip -sel clipboard).
What I have tried?
If the first line (Enter master password) were not there, I would have done:
./my-cli-tool |
while read -r USER PASSWORD
do
echo $USER
echo -n $PASSWORD | xclip -sel clipboard
done
But my issue is that I should type the master password when the prompt asks for, and so the first line is always printed. I have tried to run ./my-cli-tool | tail -1: the prompt is not shown, although if I type the master password, it only prints user1 Passw0rd!, so I can do the command above to copy the password into the clipboard.
Question
Do you have any idea to:
always show the prompt on screen for the master password
only print the user
copy the password to the clipboard
Expected output
Basically, I would like that kind of output:
$ ./my-cli-tool | solution
Enter master password: ********
user1
And have Passw0rd! copied into my clipboard.
I've simply modified your answer a little bit -
./my-cli-tool | {
x=$(dd bs=1 count=1 2>/dev/null)
while [ "$x" != : ]; do
printf %c "$x";
x=$(dd bs=1 count=1 2>/dev/null)
done
printf %s ": "
while read -r USER PASSWORD
do
echo $USER
echo -n $PASSWORD | xclip -sel clipboard
done
}
Lemme know if it works.
EDIT: Updated logic. Uses dd.
I'm trying to create a bash script that asks for password when you try to see the password file, but I'm stucked. This is my code:
#!/bin/bash
# Read Password
echo -n Password:
read -s PASSWORD
passwords() {
echo "
PASSWORDS
"
}
if [ "$PASSWORD"="root" ]; then
passwords
exit
else
echo "Wrong password"
exit
fi
I've tried a lot of things, for example if [ "$PASSWORD"!="root" ] instead of else but none of them worked.
Here is a shorter version:
#!/bin/bash
passwords(){
echo "PASSWORDS"
}
## Read Password
read -p "Enter password: " -s PASSWORD
desired_password="root"
[ "$PASSWORD" == "$desired_password" ] && passwords || echo "Wrong password"
As #vdavid said, you can add a space around the equal sign or even better, as you have bash shell, it is recommended to use double-bracket for your if statement. Check this: Is there any difference between '=' and '==' operators in bash or sh
Also you can add:
printf "/n" so your script will behave like a typical Linux prompt for password - information will output in new line
non-zero exit code in case of wrong password (exit 1)
Basically, after those improvements code looks like this:
#!/bin/bash
# Read Password
echo -n Password:
read -s PASSWORD
printf "\n"
passwords() {
echo "PASSWORDS"
}
if [[ "$PASSWORD" == "root" ]]; then
passwords
exit 0
else
echo "Wrong password"
exit 1
fi
Note that I used "==" instead of "=", but for double-bracket they both do the same job.
This question already has answers here:
Hiding user input on terminal in Linux script
(9 answers)
Closed 3 years ago.
I am creating a script that is used for creating an user account. I want to hide the characters of the password while the user is prompted to enter the password
I tried to use read -ps but I get
./account.sh: line 26: read: `Password: ': not a valid identifier
Here is my code
#!/bin/bash
# Check if user is Root
if [[ ${UID} -ne '0' ]]
then
echo 'You are not autharized for this process'
exit
fi
# Ask for full name
read -p 'Full Name: ' full_name # Set the input data to "full_name" variable
# Ask for user name
read -p 'User Name: ' user_name # Set the input data to "user_name" variable
# Check for user name length
username_length=${#user_name}
if [[ ${username_length} -lt 3 ]]
then
echo 'User name should be at least 3 characters'
exit
fi
# Ask for password
read -ps 'Password: ' password # Set the input data to "password" variable
# Check for password length
password_length=${#password}
if [[ ${password_length} -lt 8 ]]
then
echo 'Password should be at least 8 characters'
exit
fi
# Create the user
useradd -c "${comment}" -m ${user_name}
# Set the password for the user
echo -e "$password\n$password" | passwd "$user_name"
# Change password on first login
passwd -e ${user_name}
for your example you could use
read -p -s 'Password: ' password
ps friendly reminder to never store passwords in plain text
I have the following script:
#!/bin/bash
#
# Example script for validating SVN credentials.
var_svn_user_name=
var_svn_password=
function get_svn_credentials()
{
# First, get the credentials from the user
read -r -p "Please enter SVN User Name: " var_svn_user_name
echo -n "Please enter SVN Password: "
read -r -s var_svn_password
echo ""
echo "----------------"
echo "The SVN User Name is: ${var_svn_user_name}"
echo "The SVN User Password is: ${var_svn_password}"
# Next, validate provided credentials
echo -n "Validating credentials... "
#var_ret=$(svn list --username "${var_svn_user_name}" --password \
# "${var_svn_password}" ${var_url} ${var_cfg} ${var_opt}=${var_val} \
# --no-auth-cache --non-interactive 2>&1 | grep "Authentication failed")
if [[ $var_ret == "" ]]
then
echo 'Success'
else
echo 'Failed'
fi
}
function main()
{
# EXAMPLE Call #1
#result=$(get_svn_credentials) # FAILURE
# EXAMPLE Call #2
get_svn_credentials # SUCCESS
echo "Return value is: $result"
if [[ $var_ret == "Success" ]]
then
echo "SVN User Name and Password was validated."
else
echo "SVN User Name and Password was NOT validated."
fi
}
main "$#"
Why is it that when I comment out Example 2 and uncomment Example 1, the echoing of password does not get displayed until read executes?
I am trying to figure out how to get the return statement to work like a C function style return statement.
Would anyone be able to help with this?
You are writing your prompt to standard output, which is captured by the command substitution. Write it to standard error instead (like read -p does).
function get_svn_credentials()
{
# First, get the credentials from the user
read -r -p "Please enter SVN User Name: " var_svn_user_name
echo -n "Please enter SVN Password: " >&2
read -r -s var_svn_password
{
echo ""
echo "----------------"
echo "The SVN User Name is: ${var_svn_user_name}"
echo "The SVN User Password is: ${var_svn_password}"
} >&2
# Next, validate provided credentials
echo -n "Validating credentials... "
#var_ret=$(svn list --username "${var_svn_user_name}" --password \
# "${var_svn_password}" ${var_url} ${var_cfg} ${var_opt}=${var_val} \
# --no-auth-cache --non-interactive 2>&1 | grep "Authentication failed")
if [[ $var_ret == "" ]]
then
echo 'Success'
else
echo 'Failed'
fi
}
That said, don't rely on the output to determine if it succeeded or not; just use the exit status.
get_svn_credentials () {
local user_name password
# First, get the credentials from the user
read -r -p "Please enter SVN User Name: " user_name
read -r -p "Please enter SVN Password: " -s password
{
echo ""
echo "----------------"
echo "The SVN User Name is: ${user_name}"
echo "The SVN User Password is: ${password}"
} >&2
# Next, validate provided credentials
# Let the exit status of grep -q be the exit status
# of the function
printf '%s\n' "Validating credentials... " >&2
svn list --username "${user_name}" \
--password "${password}" \
"${var_url}" ${var_cfg} "${var_opt}=${var_val}" \
--no-auth-cache --non-interactive 2>&1 |
grep -q "Authentication failed"
}
main () {
if get_svn_credentials
then
echo "SVN User Name and Password was validated."
else
echo "SVN User Name and Password was NOT validated."
fi
}
main
(Note: you should probably be quoting $var_cfg, but it's possible it is actually a list of options. In that case, you should be using an array instead, but as it's impossible to tell from this code alone, I've left it unquoted.)
I created the following BASH script that works perfectly for getting a password from the user:
while [ -z "$PASSWORD" ]
do
echo "Please enter a password:"
read -s PASSWORD1
echo "Please re-enter the password to confirm:"
read -s PASSWORD2
if [ "$PASSWORD1" = "$PASSWORD2" ]; then
PASSWORD=$PASSWORD1
else
# Output error message in red
red='\033[0;31m'
NC='\033[0m' # No Color
echo ""
echo -e "${red}Passwords did not match!${NC}"
fi
done
# This is just here to prove script works
echo "password is: $PASSWORD"
However, if I place it in a function, it stops working:
function getPasswordFromUser()
{
while [ -z "$PASSWORD" ]
do
echo "Please enter a password:"
read -s PASSWORD1
echo "Please re-enter the password to confirm:"
read -s PASSWORD2
if [ "$PASSWORD1" = "$PASSWORD2" ]; then
PASSWORD=$PASSWORD1
else
# Output error message in red
red='\033[0;31m'
NC='\033[0m' # No Color
echo ""
echo -e "${red}Passwords did not match!${NC}"
fi
done
echo $PASSWORD
}
PASSWORD=$(getPasswordFromUser)
# This is just here to check if script worked
echo "got password $PASSWORD"
If I change the call to the function from PASSWORD=$(getPasswordFromUser) to: getPasswordFromUser; then the method starts "working" but the password is output to the screen, and I haven't captured it.
Is there a way to update this BASH script so that I can call a function to get a password from the user without the password ever being displayed in the terminal?
In case it matters, this is for Debian/Ubuntu.
If you call the function like myvar=$(myfunction) it will catch the first echo statement.
What you can do, instead, is to define a variable within the function and then access it. There is no scope in bash, so you will be able to access it once the function has been executed.
See an example on each one of them:
$ cat a
#!/bin/bash
function myf()
{
echo "heeeiiii"
echo "hellO"
}
function myf2()
{
echo "lets define var MYTEST"
MYTEST="this is my test"
}
r=$(myf)
echo "this is myf: $r"
echo "MYTEST=$MYTEST"
myf2
echo "MYTEST=$MYTEST"
Execution:
$ ./a
this is myf: heeeiiii
hellO
MYTEST=
lets define var MYTEST
MYTEST=this is my test
Most of the output in your function should be written to standard error, not standard output.
getPasswordFromUser()
{
while [ -z "$PASSWORD" ]
do
echo "Please enter a password:" >&2
read -s PASSWORD1
echo "Please re-enter the password to confirm:" >&2
read -s PASSWORD2
if [ "$PASSWORD1" = "$PASSWORD2" ]; then
PASSWORD=$PASSWORD1
else
# Output error message in red
red='\033[0;31m'
NC='\033[0m' # No Color
echo -e "\n${red}Passwords did not match!${NC}" >&2
fi
done
echo "$PASSWORD"
}
Also, be sure to quote $PASSWORD in the final line; someone may use multiple runs of whitespace or shell glob characters in their password!
Your first attempt is correct:
~$ PASSWORD=$(getPasswordFromUser)
~$ echo $PASSWORD
Please enter a password: Please re-enter the password to confirm: a
You just don't see the "Please enter a password" because it is captured by the $(..).
You have several possibilities:
use a global variable
use different descriptor
have the function take a variable as the first arg and modify the variable with the string you want to return.
Some examples can be found in how to return a string value from a bash function, the Advanced Bash-Scripting Guide, or the linux journal.