Change Unix password from command line over Python/Fabric

You could feed the new and old passwords into passwd using echo e.g.

echo -e "oldpass\\nnewpass\\nnewpass" | passwd

(the -e option for echo enables interpretation of backslash escapes so the newlines are interpreted as such)


The trick is to use a combination of usermod and Python’s crypt to change your password:

from crypt import crypt
from getpass import getpass
from fabric.api import *

def change_password(user):
    password = getpass('Enter a new password for user %s:' % user)
    crypted_password = crypt(password, 'salt')
    sudo('usermod --password %s %s' % (crypted_password, user), pty=False)

I use chpasswd on Ubuntu 11.04

fabric.api.sudo('echo %s:%s | chpasswd' % (user, pass))

Note: Normally this pattern doesn't work:

$ sudo echo bla | restricted_command

because only the 'echo' gets elevated privileges, not the 'restricted_command'.

However, here it works because when fabric.api.sudo is caled with shell=True (the default), fabric assembles the command like this:

$ sudo -S -p <sudo_prompt> /bin/bash -l -c "<command>"

sudo spawns a new shell (/bin/bash), running with root privileges, and then that escalated shell runs the command.

Another way to pipe with sudo is to use sudo tee: