可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm writing a shell script to automatically add a new user and update their password. I don't know how to get passwd to read from the shell script instead of interactively prompting me for the new password. My code is below.
adduser $1
passwd $1
$2
$2
回答1:
from "man 1 passwd
":
--stdin
This option is used to indicate that passwd should read the new
password from standard input, which can be a pipe.
So in your case
adduser "$1"
echo "$2" | passwd "$1" --stdin
[Update] a few issues were brought up in the comments:
Your passwd
command may not have a --stdin
option: use the chpasswd
utility instead, as suggested by ashawley.
If you use a shell other than bash, "echo" might not be a builtin command,
and the shell will call /bin/echo
. This is insecure because the password
will show up in the process table and can be seen with tools like ps
.
In this case, you should use another scripting language. Here is an example in Perl:
#!/usr/bin/perl -w
open my $pipe, '|chpasswd' or die "can't open pipe: $!";
print {$pipe} "$username:$password";
close $pipe
回答2:
The only solution works on Ubuntu 12.04:
echo -e "new_password\nnew_password" | (passwd user)
But the second option only works when I change from:
echo "password:name" | chpasswd
To:
echo "user:password" | chpasswd
See explanations in original post: Changing password via a script
回答3:
Read the wise words from:
I quote:
Nothing you can do in bash can possibly work. passwd(1) does not read from standard input. This is intentional. It is for your protection. Passwords were never intended to be put into programs, or generated by programs. They were intended to be entered only by the fingers of an actual human being, with a functional brain, and never, ever written down anywhere.
Nonetheless, we get hordes of users asking how they can circumvent 35 years of Unix security.
It goes on to explain how you can set your shadow(5)
password properly, and shows you the GNU-I-only-care-about-security-if-it-doesn't-make-me-think-too-much-way of abusing passwd(1)
.
Lastly, if you ARE going to use the silly GNU passwd(1) extension --stdin
, do not pass the password putting it on the command line.
echo $mypassword | passwd --stdin # Eternal Sin.
echo "$mypassword" | passwd --stdin # Eternal Sin, but at least you remembered to quote your PE.
passwd --stdin <<< "$mypassword" # A little less insecure, still pretty insecure, though.
passwd --stdin < "passwordfile" # With a password file that was created with a secure `umask(1)`, a little bit secure.
The last is the best you can do with GNU passwd
. Though I still wouldn't recommend it.
Putting the password on the command line means anyone with even the remotest hint of access to the box can be monitoring ps
or such and steal the password. Even if you think your box is safe; it's something you should really get in the habit of avoiding at all cost (yes, even the cost of doing a bit more trouble getting the job done).
回答4:
Nowadays, you can use this command:
echo "user:pass" | chpasswd
回答5:
For those who need to 'run as root' remotely through a script logging into a user account in the sudoers file, I found an evil horrible hack, that is no doubt very insecure:
sshpass -p 'userpass' ssh -T -p port user@server << EOSSH
sudo -S su - << RROOT
userpass
echo ""
echo "*** Got Root ***"
echo ""
#[root commands go here]
useradd -m newuser
echo "newuser:newpass" | chpasswd
RROOT
EOSSH
回答6:
You could use chpasswd
echo $1:$2 | chpasswd
回答7:
Have you looked at the -p
option of adduser
(which AFAIK is just another name for useradd
)? You may also want to look at the -P
option of luseradd
which takes a plaintext password, but I don't know if luseradd
is a standard command (it may be part of SE Linux or perhaps just an oddity of Fedora).
回答8:
Tested this on a CentOS VMWare image that I keep around for this sort of thing. Note that you probably want to avoid putting passwords as command-line arguments, because anybody on the entire machine can read them out of 'ps -ef'.
That said, this will work:
user="$1"
password="$2"
adduser $user
echo $password | passwd --stdin $user
回答9:
Sometimes it is useful to set a password which nobody knows. This seems to work:
tr -dc A-Za-z0-9 < /dev/urandom | head -c44 | passwd --stdin $user
回答10:
This is the definitive answer for a teradata node admin.
Go to your /etc/hosts
file and create a list of IP's or node names in a text file.
SMP007-1
SMP007-2
SMP007-3
Put the following script in a file.
#set a password across all nodes
printf "User ID: "
read MYUSERID
printf "New Password: "
read MYPASS
while read -r i; do
echo changing password on "$i"
ssh root@"$i" sudo echo "$MYUSERID":"$MYPASS" | chpasswd
echo password changed on "$i"
done< /usr/bin/setpwd.srvrs
Okay I know I've broken a cardinal security rule with ssh and root
but I'll let you security folks deal with it.
Now put this in your /usr/bin
subdir along with your setpwd.srvrs
config file.
When you run the command it prompts you one time for the User ID
then one time for the password. Then the script traverses all nodes
in the setpwd.srvrs
file and does a passwordless ssh to each node,
then sets the password without any user interaction or secondary
password validation.
回答11:
I stumbled upon the same problem and for some reason the --stdin
option was not available on the version of passwd
I was using (shipped in Ubuntu 14.04).
If any of you happen to experience the same issue, you can work it around as I did, by using the chpasswd
command like this:
echo "<user>:<password>" | chpasswd
回答12:
You can use the expect
utility to drive all programs that read from a tty (as opposed to stdin, which is what passwd does). Expect comes with ready to run examples for all sorts of interactive problems, like passwd entry.