从一个shell脚本中使用passwd命令。

时间:2021-10-11 14:38:55

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.

我正在编写一个shell脚本来自动添加一个新用户并更新他们的密码。我不知道如何从shell脚本中读取passwd,而不是交互式地提示我输入新密码。我的代码如下。

adduser $1
passwd $1
$2
$2

12 个解决方案

#1


72  

from "man 1 passwd":

从“人1密码”:

   --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.

您的passwd命令可能没有——stdin选项:使用chpasswd实用程序代替,正如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.

如果您使用的shell不是bash,“echo”可能不是一个内置命令,而shell将调用/bin/ echo。这是不安全的,因为密码会出现在进程表中,并且可以通过ps等工具看到。

In this case, you should use another scripting language. Here is an example in Perl:

在这种情况下,您应该使用另一种脚本语言。下面是Perl中的一个例子:

#!/usr/bin/perl -w
open my $pipe, '|chpasswd' or die "can't open pipe: $!";
print {$pipe} "$username:$password";
close $pipe

#2


41  

The only solution works on Ubuntu 12.04:

唯一的解决方案适用于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


25  

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.

您在bash中所能做的任何事情都不可能奏效。passwd(1)不从标准输入读取。这是故意的。这是为了你的保护。密码从来都不打算放在程序中,或者是由程序生成的。它们只是被一个活生生的人的手指所进入,大脑功能正常,从来没有在任何地方被记录下来。

Nonetheless, we get hordes of users asking how they can circumvent 35 years of Unix security.

尽管如此,我们还是有大量的用户询问他们如何能够规避35年的Unix安全。

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).

它接着解释了如何正确设置你的影子(5)密码,并向你展示了“gnui -i -on - card -about-security-if- It -”- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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.

最后,如果您打算使用愚蠢的GNU passwd(1)扩展——stdin,不要将密码放在命令行中。

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.

最后是您可以使用GNU passwd的最好方法。虽然我还是不推荐它。

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).

在命令行上输入密码意味着,即使是对该框进行最远程的访问,也可以监视ps或这样的操作,并窃取密码。即使你认为你的盒子是安全的;这是你真正应该养成的一种习惯:不惜一切代价避免(是的,甚至是为了完成工作而付出更多的代价)。

#4


18  

Nowadays:

现在:

echo "user:pass" | chpasswd

回声”用户:通过“| chpasswd

#5


1  

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'.

我在一个CentOS VMWare图像上做了测试,我一直在做这类事情。注意,您可能希望避免将密码作为命令行参数,因为整个机器上的任何人都可以从“ps -ef”中读取它们。

That said, this will work:

也就是说,这将起作用:

user="$1"
password="$2"
adduser $user
echo $password | passwd --stdin $user

#6


1  

You could use chpasswd

您可以使用chpasswd

echo $1:$2 | chpasswd

echo $ 1:$ 2 | chpasswd

#7


0  

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).

您是否查看了adduser的-p选项(AFAIK只是useradd的另一个名称)?您可能还想看看luseradd的-P选项,它采用明文密码,但我不知道luseradd是否是一个标准命令(它可能是SE Linux的一部分,或者可能只是Fedora的一个奇怪的地方)。

#8


0  

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.

您可以使用expect实用程序来驱动从tty读取的所有程序(与stdin相反,这是passwd所做的)。Expect可以为各种交互式问题(比如passwd条目)运行示例。

#9


0  

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


0  

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 on a Ubuntu 14.04).

我遇到了同样的问题,出于某种原因,“——stdin”选项在我使用的passwd版本中没有(在Ubuntu 14.04上发布)。

If any of you happen to experiment the same, you can work it around as I did: by using the chpasswd command like this:

如果你们中的任何一个碰巧都做了相同的实验,你可以像我一样做:通过使用chpasswd这样的命令:

echo "<user>:<password>" | chpasswd

回声“ <用户名> : <密码> ”| chpasswd

#11


0  

This is the definitive answer for a teradata node admin

这是teradata节点管理的最终答案。

1: goto your /etc/hosts file and create a list of IP's or node names in a text file

1:goto your /etc/hosts文件,并在文本文件中创建IP或节点名的列表。

------------------config file for servers begin ------------
SMP007-1
SMP007-2
SMP007-3
------end file leave out these comments from the cfg file---

------------------ --------- SMP007-1 SMP007-2 SMP007-3 ------------------ ------------------ ------------------ -----------------

now the script

set a password across all nodes

printf "User ID: "
read MYUSERID
printf "New Password: "
read MYPASS

“用户ID:”读取MYUSERID printf“新密码:”读取MYPASS。

for i in `cat /usr/bin/setpwd.srvrs `
do
echo changing password on $i
ssh root@$i sudo echo "$MYUSERID":"$MYPASS" | chpasswd
echo password changed on $i
done

我在“cat /usr/bin/setpwd.”。srvrs ' do echo change password on $i ssh root@$i sudo echo "$MYUSERID":"$MYPASS" | chpasswd echo密码更改为$i done。

okay I know I've broken a cardinal security rule with ssh and root but I'll let you security folks deal with it

好吧,我知道我已经用ssh和root破坏了一个基本的安全规则,但是我会让你安全的人来处理它。

_________________________________
put this in your /usr/bin subdir along with your setpwd.srvrs config file

_________________________________把这个在你的工作随着你setpwd子目录。srvrs配置文件

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 does a passwordless ssh to each node
then sets the password without any user interaction or secondary
password validation. Now how many times have you wanted to do this
but didn't know how? With great need, comes great innovation.

Think how useful something like this is to an admin with hundreds
of servers.

当您运行该命令时,它会提示您一次输入用户ID,然后一次输入密码。然后脚本遍历setpwd中的所有节点。srvrs文件对每个节点进行无密码的ssh,然后设置密码,不需要任何用户交互或二级密码验证。有多少次你想做这个但不知道怎么做?有了巨大的需求,就有了伟大的创新。想想这对一个有几百个服务器的管理员来说是多么有用。

#12


0  

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:

对于那些需要通过在sudoers文件中登录到用户帐户的脚本远程运行的用户,我发现了一个可怕的可怕的黑客,这无疑是非常不安全的:

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

#1


72  

from "man 1 passwd":

从“人1密码”:

   --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.

您的passwd命令可能没有——stdin选项:使用chpasswd实用程序代替,正如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.

如果您使用的shell不是bash,“echo”可能不是一个内置命令,而shell将调用/bin/ echo。这是不安全的,因为密码会出现在进程表中,并且可以通过ps等工具看到。

In this case, you should use another scripting language. Here is an example in Perl:

在这种情况下,您应该使用另一种脚本语言。下面是Perl中的一个例子:

#!/usr/bin/perl -w
open my $pipe, '|chpasswd' or die "can't open pipe: $!";
print {$pipe} "$username:$password";
close $pipe

#2


41  

The only solution works on Ubuntu 12.04:

唯一的解决方案适用于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


25  

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.

您在bash中所能做的任何事情都不可能奏效。passwd(1)不从标准输入读取。这是故意的。这是为了你的保护。密码从来都不打算放在程序中,或者是由程序生成的。它们只是被一个活生生的人的手指所进入,大脑功能正常,从来没有在任何地方被记录下来。

Nonetheless, we get hordes of users asking how they can circumvent 35 years of Unix security.

尽管如此,我们还是有大量的用户询问他们如何能够规避35年的Unix安全。

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).

它接着解释了如何正确设置你的影子(5)密码,并向你展示了“gnui -i -on - card -about-security-if- It -”- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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.

最后,如果您打算使用愚蠢的GNU passwd(1)扩展——stdin,不要将密码放在命令行中。

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.

最后是您可以使用GNU passwd的最好方法。虽然我还是不推荐它。

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).

在命令行上输入密码意味着,即使是对该框进行最远程的访问,也可以监视ps或这样的操作,并窃取密码。即使你认为你的盒子是安全的;这是你真正应该养成的一种习惯:不惜一切代价避免(是的,甚至是为了完成工作而付出更多的代价)。

#4


18  

Nowadays:

现在:

echo "user:pass" | chpasswd

回声”用户:通过“| chpasswd

#5


1  

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'.

我在一个CentOS VMWare图像上做了测试,我一直在做这类事情。注意,您可能希望避免将密码作为命令行参数,因为整个机器上的任何人都可以从“ps -ef”中读取它们。

That said, this will work:

也就是说,这将起作用:

user="$1"
password="$2"
adduser $user
echo $password | passwd --stdin $user

#6


1  

You could use chpasswd

您可以使用chpasswd

echo $1:$2 | chpasswd

echo $ 1:$ 2 | chpasswd

#7


0  

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).

您是否查看了adduser的-p选项(AFAIK只是useradd的另一个名称)?您可能还想看看luseradd的-P选项,它采用明文密码,但我不知道luseradd是否是一个标准命令(它可能是SE Linux的一部分,或者可能只是Fedora的一个奇怪的地方)。

#8


0  

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.

您可以使用expect实用程序来驱动从tty读取的所有程序(与stdin相反,这是passwd所做的)。Expect可以为各种交互式问题(比如passwd条目)运行示例。

#9


0  

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


0  

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 on a Ubuntu 14.04).

我遇到了同样的问题,出于某种原因,“——stdin”选项在我使用的passwd版本中没有(在Ubuntu 14.04上发布)。

If any of you happen to experiment the same, you can work it around as I did: by using the chpasswd command like this:

如果你们中的任何一个碰巧都做了相同的实验,你可以像我一样做:通过使用chpasswd这样的命令:

echo "<user>:<password>" | chpasswd

回声“ <用户名> : <密码> ”| chpasswd

#11


0  

This is the definitive answer for a teradata node admin

这是teradata节点管理的最终答案。

1: goto your /etc/hosts file and create a list of IP's or node names in a text file

1:goto your /etc/hosts文件,并在文本文件中创建IP或节点名的列表。

------------------config file for servers begin ------------
SMP007-1
SMP007-2
SMP007-3
------end file leave out these comments from the cfg file---

------------------ --------- SMP007-1 SMP007-2 SMP007-3 ------------------ ------------------ ------------------ -----------------

now the script

set a password across all nodes

printf "User ID: "
read MYUSERID
printf "New Password: "
read MYPASS

“用户ID:”读取MYUSERID printf“新密码:”读取MYPASS。

for i in `cat /usr/bin/setpwd.srvrs `
do
echo changing password on $i
ssh root@$i sudo echo "$MYUSERID":"$MYPASS" | chpasswd
echo password changed on $i
done

我在“cat /usr/bin/setpwd.”。srvrs ' do echo change password on $i ssh root@$i sudo echo "$MYUSERID":"$MYPASS" | chpasswd echo密码更改为$i done。

okay I know I've broken a cardinal security rule with ssh and root but I'll let you security folks deal with it

好吧,我知道我已经用ssh和root破坏了一个基本的安全规则,但是我会让你安全的人来处理它。

_________________________________
put this in your /usr/bin subdir along with your setpwd.srvrs config file

_________________________________把这个在你的工作随着你setpwd子目录。srvrs配置文件

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 does a passwordless ssh to each node
then sets the password without any user interaction or secondary
password validation. Now how many times have you wanted to do this
but didn't know how? With great need, comes great innovation.

Think how useful something like this is to an admin with hundreds
of servers.

当您运行该命令时,它会提示您一次输入用户ID,然后一次输入密码。然后脚本遍历setpwd中的所有节点。srvrs文件对每个节点进行无密码的ssh,然后设置密码,不需要任何用户交互或二级密码验证。有多少次你想做这个但不知道怎么做?有了巨大的需求,就有了伟大的创新。想想这对一个有几百个服务器的管理员来说是多么有用。

#12


0  

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:

对于那些需要通过在sudoers文件中登录到用户帐户的脚本远程运行的用户,我发现了一个可怕的可怕的黑客,这无疑是非常不安全的:

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