Automating Password Changes on Linux: passwd, chpasswd, and Safer Methods
The passwd command is designed for interactive use—it prompts for input rather than accepting passwords via stdin by default. When you need to set passwords programmatically (bulk user provisioning, CI/CD automation, remote administration), you need methods that bypass the interactive prompt.
Using passwd with –stdin
The --stdin flag tells passwd to read the new password from standard input:
echo "newpassword" | passwd --stdin username
This works on most modern distributions (RHEL/CentOS, Fedora, Debian/Ubuntu, AlmaLinux, Rocky Linux). However, some systems disable --stdin via PAM configuration for security reasons. If you get “passwd: unrecognized option ‘–stdin’”, use an alternative method.
Piping Multiple Inputs
If --stdin isn’t available, pipe the password twice with newlines:
echo -e "newpassword\nnewpassword" | passwd username
The -e flag tells echo to interpret escape sequences. This works because passwd normally asks for the password twice to prevent typos.
For changing your own password as a regular user, provide the current password first, then the new password twice:
echo -e "currentpass\nnewpass\nnewpass" | passwd
Using chpasswd for Batch Operations
For multiple password changes on a single system, chpasswd is more efficient than spawning multiple passwd processes:
echo "user1:password1" | chpasswd
echo "user2:password2" | chpasswd
Or load from a file with username:password format on each line:
chpasswd < passwordfile.txt
Specify the encryption method with the -c option:
echo "user1:newpass" | chpasswd -c SHA512
Verify the encryption in the shadow file:
sudo grep user1 /etc/shadow
Remote Password Changes
Combine these methods with SSH for bulk operations across servers:
ssh user@remotehost 'echo "newpass" | passwd --stdin targetuser'
For multiple servers:
for server in server1 server2 server3; do
ssh root@$server "echo 'newpass' | passwd --stdin targetuser"
done
Using IP ranges:
for ((i=1; i<=100; i++)); do
ssh root@10.1.0.$i "echo 'newpass' | passwd --stdin targetuser"
done
Creating Users with Initial Passwords
Combine user creation and password setting in one operation:
ssh remotehost 'useradd -m -s /bin/bash newuser && echo "initialpass" | passwd --stdin newuser'
Add the user to supplementary groups during creation:
ssh remotehost 'useradd -m -s /bin/bash -G sudo,docker newuser && echo "pass123" | passwd --stdin newuser'
Set the user’s home directory with specific permissions:
ssh remotehost 'useradd -m -d /home/newuser -s /bin/bash newuser && echo "pass123" | passwd --stdin newuser && chmod 750 /home/newuser'
Why Non-Interactive Passwords Are Risky
Passwords visible in command lines can be read by:
- Other users via
ps,ps aux, or/proc/<pid>/cmdline - Shell history files (
.bash_history,.zsh_history) - SSH server logs and authentication logs
- Process monitoring tools and container image layers
- Reverse history search in interactive shells
Non-interactive password methods should only be used when:
- Operating in isolated environments or CI/CD systems with restricted access
- Passwords are temporary and users change them on first login
- You control all systems in the pipeline
- Interactive prompts aren’t feasible
Secure Alternatives
SSH key-based authentication — Eliminates password use entirely:
ssh-copy-id -i ~/.ssh/id_rsa.pub user@remotehost
Force password change on first login — Use chage to expire the initial password:
chage -d 0 newuser
This sets the password change date to epoch, forcing a password change at next login.
Configuration management tools — Ansible, Terraform, and Puppet support secure credential handling with vaults, encrypted variables, and secret backends:
# Ansible with vault
ansible-vault create group_vars/webservers/vault.yml
# Then reference: {{ vault_password }}
Centralized authentication — LDAP, Active Directory, FreeIPA, or RADIUS offload password management and policy enforcement to dedicated servers.
Credential vaults — HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, or 1Password for Business:
# HashiCorp Vault example
vault kv put secret/newuser password="$(openssl rand -base64 16)"
Generate temporary credentials at runtime instead of embedding them in scripts.
Never hardcode production passwords in scripts, container images, configuration files, or version control. Use environment variables from secure sources, read from credential managers at runtime, or implement interactive prompts for sensitive deployments.

Very useful to automation on several GNU/Linux servers deployement.
Matias Colli
UNIX/Linux SysAdmin
I got a problem,
when I was trying to changing the password of aaa,
sudo echo -e "abcd1234\nabcd1234" | passwd aaahowever, error pumps up,
passwd: You may not view or modify password information for aaa
I think there are some security setting with the system, which did not allow me to do so,
how to solve this out.
thanks a lot.
You may try
echo -e "abcd1234nabcd1234" | sudo passwd aaaor
echo -e "abcd1234" | sudo passwd --stdin aaaNeither solution works for /bin/sh
Enter new UNIX password: Retype new UNIX password: passwd: Authentication token manipulation error
passwd: password unchanged
They work only for /bin/bash
Any solution to /bin/sh?
Thanks in advance
Did it work for you under /bin/bash? That’s interesting.
What’s your exact command and the output?
And which OS are you working on? I believe my OS (Fedora 22) has quite different messages printed out from yours:
$ passwd
Changing password for user zma.
Changing password for zma.
(current) UNIX password:
Showing us `passwd –help` will also be helpful to answer your question.
echo -e “changedpassword\ntestingpassword\ntestingpassword” | passwd
I wrote it as a shell script and executed but password authentication failure.
the same code is exucuted on a terminal and seems to be working fine
how can i solve the problem
Did you write your shell script on a windows machine then upload it to the linux machine?
What if I have normal user access on each remote server and I want to change all remote servers
password which contains same username. I think it will ask for password if haven’t configure password less auth.
In this case what command helps.
Thanks in advance
Hi Sumit, it is not impossible. You may use the Password-based “password-less” ssh login if your passwords on all these servers are the same or can be programmatically generated to be passed to sshpass.
its giving token manipulation error.
for ((i=1;i<=100;i++)); do ssh 10.1.0.$i 'echo -e "linuxpassword\nlinuxpassword" | passwd linuxuser'; done;
firstly its giving error that only root user can specify the username as I was logging with a standard user.
After this I tried with this one
for ((i=1;i<=100;i++)); do ssh 10.1.0.$i 'echo -e "linuxpassword\nlinuxpassword" | passwd '; done;
then its token manipulation error.
thanks a lot
When you update your own password, `passwd` command requires 3 input, one of your current password and twice of your new password. So the command may be:
what if the list of ip addresses of servers’s in a text file.
In general, you have at least two methods to do actions to each item in a line in a text file txt:
Here, there should be no space in each item.
or
You can replace the `echo $i` with the actions you would like to do (calling passwd in this example).
Hi,
I tried your provided method on changing password of SUN Solaris but somehow solaris is not taking provided password parameter and post hitting enter asking password.
please help.
Unix like Solaris may have a different convention for the `passwd` command. The `–stdin` method seems not supported. I am not sure whether the 2nd method works. Sorry, I did not have a Solaris to test.
When -e is in effect, escaped characters will be interpreted. Instead of “When ‘-e‘ is in effect, ‘n‘ in echo’s input is echoed as “new line”.” Just a minor tweak for clarity. Thank you for the tip. Used it in a script to set up new servers quickly!
Glad to know it helps! Yes, that is more clearer with the “escaped characters” as a whole picture of the meaning. Improved the post. Thanks!
Hi,
I also have a SOLARIS based machine. I want to find a solution to change the password with only one line because I want to change it via Java app. I tried lots of versions of echo but no success.
Please, can someone give a solution to change the password on a SOLARIS based server? It would be much appreciated. PS: i am just a basic user, not the root.
I’ve had a hard time getting this to work, I was getting this:
echo -e “linuxpassword\nlinuxpassword” | passwd linuxuser
Enter new UNIX password: Retype new UNIX password: Sorry, passwords do not match
passwd: Authentication token manipulation error
passwd: password unchanged
Turns out that I was on sh instead of bash as it is the default shell for docker build…
I had to tell it to use bash in the dockerfile like so:
RUN [“/bin/bash”, “-c”, “echo -e ‘linuxpassword\nlinuxpassword’ | passwd linuxuser”]
You may try the `passwd –stdin` method if the `passwd` in your environment is modern enough to accept `–stdin`.
HI Eric,
Thanks for the post. My question is I have to change root password on 100 plus servers with different passwords which should generate using mkpasswd like # mkpasswd -l 8 -d 1 -c 0 -s 1 and generated passwords along with server names should store in a file. How can we achieve this though script. Thanks in advance for your support.
Example : This is for single server. Want it for 100 servers where my servers name is stored in servernames.txt file as
server1
server2
#!/bin/bash
usepasswd=$(mkpasswd -l 8 -d 1 -c 0 -s 1)
echo “$usepasswd” > /root/rpwansiclient.txt
ssh root@server1 “echo $usepasswd|passwd root –stdin”
#
Regards,
Vasu
You can extend your script by using a `for` loop. For example,
#!/bin/bash
for svr in `cat servernames.txt`; do
usepasswd=$(mkpasswd -l 8 -d 1 -c 0 -s 1)
echo “$svr $usepasswd” >> /root/rpwansiclient.txt
ssh root@$svr “echo $usepasswd | passwd root –stdin”
done
Thanks a lot Eric for the needful help.
Thanks,
Vasu
Does this cause security concerns with the username and password contained all on the same command line? I thought all commands were logged somewhere.
If you are running under ‘root’ in bash, the command is logged under ~/.bash_history. This file should be only accessible by root by common Linux configurations.
During the execution of the command, there is a very short period of time the other users can see the command. Putting the password in a file and then use a command like `cat passfile | passwd –stdin username` may get rid of this.
If the password is very sensitive, typing manually may be safer.
Can u create password using $ in Linux Env. ?
# echo 'your$pass' | passwd --stdin user1Changing password for user user1.
passwd: all authentication tokens updated successfully.
Thanks very much for this!
One thing I observed, is a password ending in an “!” messed with the command. for example:
echo -e “Password!\nPassword!” | passwd testuser
Fails with:
bash: !\nPassword!”: event not found
I don’t understand this enough to know why, but just wanted to pass it on
`!` is a special character in Bash http://mirror.pkill.info/ldp/LDP/LDP/abs/html/special-chars.html . “from the command line, the ! invokes the Bash history mechanism”.
Try this instead
Eric, thanks, will give that a try
Martin
Hi Eric,
The command intended for this is chpasswd
https://www.tutorialspoint.com/unix_commands/chpasswd.htm
Looks a nice tool, especially useful for batch account password changing. Thanks for sharing this.
Hi Eric,
I have One scenario.
password for my user “abc” expired.
I am trying to connect “abc” from “xyz” user via “ssh abc@IPADDRESS”(using passwordless Authentication ) and it asks below
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for user abc.
Changing password for abc.
(current) UNIX password
I dont want to make any changes in password policy or chage -l abc.
Is there any way i can connect by using “ssh abc@IPADDRESS” and skip that warning
of changing password.
Regards,
Manish J
im using ubuntu on windows 10.how to create password ?.
its asking for password while using sudo command
to me work with this sentence:
for ((i=1;i<=100;i++)); do ssh 10.1.0.$i 'echo "linuxpassword\nlinuxpassword" | passwd '; done;
While you are creating a script I recommend using it as bellow, due to probably encoding(?) differences. For example in my case ‘new line’ – ‘\n’ doesn’t work… Using the console i must type ‘^J’, and this mean ‘new line’ in my system.
echo -e “password //(just type enter)
password” | sudo passed user
Hi Sir,
I am using Oracle Solaris. May I know how do I create assign default password for new user? The example above is not working for Oracle Solaris.
Hope to hear from you.
Hi Sir,
I am using Oracle Solaris. May I know how do I create assign default password for new user? The example above is not working for Oracle Solaris.
Hope to hear from you.