Introduction
The passwd command in Unix-like systems lets users change passwords. By using it in shell scripts, we can automate and simplify password management tasks.
Interactive Approach
In the interactive approach, the passwd command will prompt the user to manually enter the new password and then re-enter it for confirmation. This is the most common method used when running the passwd command from the command line.
Example: This script prompts the user for a username and then invokes the passwd command for that user, which will then prompt the user to set a new password for the given username.
#!/bin/bash
read -p "Enter the username whose password you want to change: " username
passwd $username
Usage:
./changepass.sh
Enter the username whose password you want to change: bob
New password:
Retype new password:
passwd: password updated successfully
When you run this script, it will ask for the username and then prompt you to enter the new password for the given username twice (for confirmation).
This method is safest because the password isn't exposed in any command or script, and it's not visible to other users through commands like ps.
Here the password itself does not get stored in the command history. However, the invocation of the passwd command itself (without the password) would still appear in the history.
In the above script, we had to provide the password twice, we can change that behavior by piping the new password to the passwd command twice - once for the new password and once for its confirmation:
echo -e "$newpassword\n$newpassword" | sudo passwd "$username"
Example: The script's goal is to provide the password and its confirmation to the passwd command without the user having to type it twice.
#!/bin/bash
read -p "Please enter the username whose password you want to change: " username
if id "$username" &>/dev/null; then
echo "Please enter the new password for $username:"
read -s newpassword
echo -e "$newpassword\n$newpassword" | sudo passwd "$username"
if [ $? -eq 0 ]; then
echo "Password for $username has been changed successfully."
else
echo "Failed to change the password for $username."
fi
else
echo "User $username does not exist."
fi
Usage:
./changnotwice.sh
Please enter the username whose password you want to change: bob
Please enter the new password for bob:
New password: Retype new password: passwd: password updated successfully
Password for bob has been changed successfully.
In this example, the read command is used with -s option, which does not show input characters (useful for sensitive information like passwords).
On some systems or configurations, passwd might not support taking input from stdin in this manner. To avoid such issues and have consistent behavior across different environments, more advanced tools like expect can be used, but they introduce additional complexity. Example:
#!/usr/bin/expect -f
send_user "Enter username: "
expect_user -re "(.*)\n" {
set username $expect_out(1,string)
}
send_user "Enter new password for $username: "
expect_user -re "(.*)\n" {
set newpassword $expect_out(1,string)
}
# Start the process
spawn sudo passwd $username
expect "New password:"
send "$newpassword\r"
expect "Retype new password:"
send "$newpassword\r"
expect {
"password updated successfully" {
exit 0
}
"BAD PASSWORD:" {
send_user "Failed to update password: Bad password.\n"
exit 1
}
timeout {
send_user "Script timed out\n"
exit 2
}
}
# Done
exit 0
Usage:
./chgexpect.sh
Enter username: bob
Enter new password for bob: bob
spawn sudo passwd bob
New password:
Retype new password:
Non-interactive Approach
In the non-interactive approach, the password is supplied to the passwd command without manual intervention, typically through piping or redirection. This can be done using passwd's --stdin option (on systems that support it) or using other utilities like chpasswd.
Using --stdin option
Using the --stdin option with the passwd command is another way to change a user's password non-interactively. When using this method, the new password is provided to passwd via its standard input.
Here's how you can use the --stdin option:
#!/bin/bash
username="$1"
new_password="$2"
echo "$new_password" | sudo passwd --stdin $username
When the script runs, the new password is echoed and piped directly to the passwd command, which changes the password for the specified user.
Note: If you're seeing the error message passwd: unrecognized option '--stdin'
, it means that the passwd command on your system doesn't support the --stdin option. This option is typically available on some distributions like CentOS Stream or RHEL, but may not be present on others, like Ubuntu.
Using echo and passwd
The combination of echo and passwd is often employed to update a user's password programmatically without having to interact with the passwd command's prompts. You can pipe the password twice into passwd.
#!/bin/bash
username="$1"
new_password="$2"
echo -e "$new_password\n$new_password" | sudo passwd $username
if [ $? -eq 0 ]; then
echo "Password for $username has been changed successfully."
else
echo "Failed to change the password for $username."
fi
Usage:
./chgecho.sh bob mynewpass321
New password: Retype new password: passwd: password updated successfully
Password for bob has been changed successfully.
Alternatively, you can have the script generate a somewhat random password, after execution, the password for target_username will be changed to the generated password. Example:
#!/bin/bash
username="$1"
new_password=$(date | sha256sum | cut -c1-8)
echo -e "$new_password\n$new_password" | passwd $username
Now, when you run the script, it will use the first 8 characters from the SHA-256 hash of the current date and time as the password.
Usage:
./chgsha.sh bob
New password: Retype new password: passwd: password updated successfully
Using chpasswd
chpasswd allows you to update passwords in batch mode. It reads a list of username and password pairs from standard input and updates the passwords. Passwords must be provided in clear text (not encrypted).
Example:
#!/bin/bash
username="$1"
new_password="$2"
echo "$username:$new_password" | sudo chpasswd
if [ $? -eq 0 ]; then
echo "Password for $username has been changed successfully."
else
echo "Failed to change the password for $username."
fi
Usage:
./chgtool.sh bob mynewpass321
Password for bob has been changed successfully.
In the above example, after executing chpasswd, we manually check the exit status ($?) to determine if the command was successful (exit status 0) or if there was an error (any other exit status). Based on this, we provide custom feedback with the echo command.
Note: The chpasswd doesn't usually produce verbose output. When it successfully updates passwords, it simply returns without any message. If there's an error, it will return an error message.
Comments