如何使用 Bash 脚本自动添加用户帐户和密码?

Posted

技术标签:

【中文标题】如何使用 Bash 脚本自动添加用户帐户和密码?【英文标题】:How to automatically add user account AND password with a Bash script? 【发布时间】:2011-01-10 04:31:46 【问题描述】:

我需要能够在我的 Linux (Fedora 10) 上创建用户帐户并通过 bash 脚本(或其他方式,如果需要)自动分配密码。

通过 Bash 创建用户很容易,例如:

[whoever@server ]#  /usr/sbin/useradd newuser

是否可以在 Bash 中分配密码,功能类似于此,但自动:

[whoever@server ]# passwd newuser
Changing password for user testpass.
New UNIX password:
Retype new UNIX password: 
passwd: all authentication tokens updated successfully.
[whoever@server ]#

【问题讨论】:

为什么会跑题? 我认为这个问题是主题。现在最强烈的趋势之一是“配置即代码”的 DevOps 态度,即平台是通过“编程”一系列引导平台的管理步骤来创建的。在脚本模式下做用户管理绝对是这个编程的一部分。 作为 DevOps,我认为这是一个有用的问题(有有用的答案),但这是我的系统管理员的帽子。将其移至 SuperUser 可能更有意义。 类似问题:askubuntu.com/q/94060/250556 这也可以通过expect 脚本来解决。 【参考方案1】:

你也可以使用chpasswd:

echo username:new_password | chpasswd

所以,您将用户 username 的密码更改为 new_password

【讨论】:

+1,这是适合这项工作的工具:$ apropos chpasswd ... chpasswd (8) - update passwords in batch mode 这也适用于busybox,而passwd 不适用(没有--stdin 选项)。 chpasswd 必须以 root 权限/sudo 运行【参考方案2】:

您可以运行 passwd 命令并将其发送到管道输入。因此,请执行以下操作:

echo thePassword | passwd theUsername --stdin

【讨论】:

该方法的好处是它是安全的(假设 echo 是所用 shell 中的内置函数,这很常见),至少与 /proc/ 有关。 我必须在 13.04 上做 echo -e "password\npassword\n" | passwd --stdin 在较新的 Linux 系统中已被弃用。请改用 chpasswd。 @MarkusOrreilly 有效,但在使用 Ansible 等供应工具时无效。正如@Nybble 所说,您应该使用chpasswd。所以这是有效的:echo 'myuser:mypass' | chpasswd。希望对您有所帮助。 我很惊讶没有人提到 passwd 不能让这件事变得简单的原因:这种方法会将新密码直接放入 shell 历史记录中,除非采取措施防止这种情况发生。任何致力于走这条路的人,都应该牢记这一点。【参考方案3】:

我也在问自己同样的问题,并且不想依赖 Python 脚本。

这是在一个 bash 行中添加具有已定义密码的用户的行:

useradd -p $(openssl passwd -crypt $PASS) $USER

【讨论】:

useradd -p $(openssl passwd -1 $PASS) $USER 更现代,因为不推荐使用反引号,建议使用 $() 我遇到的一个问题:我用 zsh 的 shell 创建了我的用户,但没有意识到那时 zsh 还没有安装。如果你这样做,密码登录将失败,所以在你认为这不起作用之前(它肯定会在今天的 Arch 和 Debian 7 上工作)你可能会在全新的安装上检查它。 useradd -m -p <password> -s /bin/bash <user>, -m Crates 主目录,-s 指定用户默认 shell,替换 passworduser 以满足您的需要。 你也可以加盐密码:useradd -m -p $(openssl passwd -1 -salt $SALT $PASS)。我认为这是以后的 Ubuntu 所必需的。 @Bryson 不要使用-1,因为它使用 MD5,这不再安全。使用-crypt(至少在 OpenSSL 1.1.1 中默认)。【参考方案4】:

以下代码在 Ubuntu 14.04 中运行。尝试在其他版本/linux 变体中使用它之前。

# quietly add a user without password
adduser --quiet --disabled-password --shell /bin/bash --home /home/newuser --gecos "User" newuser

# set password
echo "newuser:newpassword" | chpasswd

【讨论】:

我不明白--gecos en.wikipedia.org/wiki/Gecos_field gecos 字段或 GECOS 字段是 Unix 和类似操作系统上 /etc/passwd 文件中的一个条目。它通常用于记录有关帐户或其用户的一般信息,例如他们的真实姓名和电话号码。 GECOS 是指通用电气综合操作系统,当 GE 的大型系统部门被出售给霍尼韦尔时,它已更名为 GCOS。 这对我来说是 Debian 8 上的正确答案,在我的服务器设置 bash 脚本上就像一个魅力! GECOS 字段基本上是一个用户描述字段。在那里写下你想要的任何东西。【参考方案5】:

我喜欢 Tralemonkey 的 echo thePassword | passwd theUsername --stdin 方法,尽管它对我来说并不像我写的那样有效。然而,这对我有用。

echo -e "$password\n$password\n" | sudo passwd $user

-e 是将\n 识别为新行。

sudo 是 Ubuntu 的 root 访问权限。

双引号是为了识别$并展开变量。

上述命令将密码和新行两次传递给passwd,这是passwd 所要求的。

如果不使用变量,我认为这可能有效。

echo -e 'password\npassword\n' | sudo passwd username

单引号就足够了。

【讨论】:

在 bash 中运行良好。但是,如果在 sh 中运行,则 -e 选项不起作用。我发现它实际上输出“-e”的困难方式。幸运的是,在 sh 中不需要 -e 选项,转义是默认的。便携版是使用 printf "password\npassword\n" | ...改为。 ubuntu 的完美答案。【参考方案6】:

以下内容适用于我并在 Ubuntu 14.04 上进行了测试。它是一种不需要任何用户输入的单行器。

sudo useradd -p $(openssl passwd -1 $PASS) $USERNAME

取自@Tralemonkey

【讨论】:

【参考方案7】:

使用主目录和密码创建 sudo 用户。

useradd -m -p $(openssl passwd -1 $PASSWORD) -s /bin/bash -G sudo $USERNAME

【讨论】:

太棒了。在部署脚本中运行良好【参考方案8】:

您可以使用 -p 选项。

useradd -p encrypted_password newuser

不幸的是,这确实需要您自己对密码进行哈希处理(passwd 会为您执行此操作)。不幸的是,似乎没有标准的实用程序来散列一些数据,所以您必须自己编写。

这是我为您编写的一个小 Python 脚本来进行加密。假设您将其命名为 pcrypt,然后您将上面的命令行写入:

useradd -p $(pcrypt $passwd) newuser

需要注意的几个警告。

    当 pcrypt 运行时,任何用户都可以通过 ps 命令看到明文。 pcrypt 使用旧式 crypt 函数 - 如果您使用更现代的东西,例如 MD5 哈希,则需要更改 pcrypt。

这里是 pcrypt:

#!/usr/bin/env python

import crypt
import sys
import random

saltchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

def salt():
    return random.choice(saltchars) + random.choice(saltchars)

def hash(plain):
    return crypt.crypt(arg, salt())

if __name__ == "__main__":
    random.seed()
    for arg in sys.argv[1:]:
        sys.stdout.write("%s\n" % (hash(arg),))

【讨论】:

感谢 R Klatchko,应该可以。我不敢相信我不知道 -p 选项。我可以自己处理散列:) perl -e 'print crypt($ARGV[0], "password")' 'mypassword' 你能解释一下,我以后如何使用密码而不是散列密码?【参考方案9】:

--stdin 不适用于 Debian。它说:

`passwd: unrecognized option '--stdin'`

这对我有用:

#useradd $USER
#echo "$USER:$SENHA" | chpasswd

这里我们可以找到一些其他的好方法:

http://www.debian-administration.org/articles/668

【讨论】:

这是正确的方法,也是影子套件维护者官方支持的唯一方法。见this bug report。【参考方案10】:

您可以在 bash 脚本中使用 expect。

来自http://www.seanodonnell.com/code/?id=21

#!/usr/bin/expect 
######################################### 
#$ file: htpasswd.sh 
#$ desc: Automated htpasswd shell script 
######################################### 
#$ 
#$ usage example: 
#$ 
#$ ./htpasswd.sh passwdpath username userpass 
#$ 
###################################### 

set htpasswdpath [lindex $argv 0] 
set username [lindex $argv 1] 
set userpass [lindex $argv 2] 

# spawn the htpasswd command process 
spawn htpasswd $htpasswdpath $username 

# Automate the 'New password' Procedure 
expect "New password:" 
send "$userpass\r" 

expect "Re-type new password:" 
send "$userpass\r"

【讨论】:

【参考方案11】:

我知道我会在几年后来,但我不敢相信没有人建议 usermod。

usermod --password `perl -e "print crypt('password','sa');"` root

见鬼,万一有人想在较旧的 HPUX 上执行此操作,您可以使用 usermod.sam

/usr/sam/lbin/usermod.sam -F -p `perl -e "print crypt('password','sa');"` username

仅当执行脚本的人是当前用户时才需要 -F。当然,您不需要使用 Perl 来创建散列。您可以使用 openssl 或许多其他命令代替它。

【讨论】:

【参考方案12】:

我已经在自己的 shell 脚本中进行了测试。

$new_username 表示新创建的用户 $new_password 表示新密码

CentOS

echo "$new_password" | passwd --stdin "$new_username"

对于 Debian/Ubuntu

echo "$new_username:$new_password" | chpasswd

对于 OpenSUSE

echo -e "$new_password\n$new_password" | passwd "$new_username"

【讨论】:

【参考方案13】:

这里有一个脚本可以为你完成......

如果需要,您可以一次性添加用户列表(或仅添加一个用户),并且每个用户都有不同的密码。作为奖励,您会在脚本的末尾看到每个用户密码的列表。 ....如果您愿意,您可以添加一些用户维护选项

喜欢:

chage -m 18 $user
chage -M 28 $user

到将设置密码年龄等的脚本。

=======

#!/bin/bash

# Checks if you have the right privileges
if [ "$USER" = "root" ]
then

# CHANGE THIS PARAMETERS FOR A PARTICULAR USE
PERS_HOME="/home/"
PERS_SH="/bin/bash"

   # Checks if there is an argument
   [ $# -eq 0 ] &&  echo >&2 ERROR: You may enter as an argument a text file containing users, one per line. ; exit 1; 
   # checks if there a regular file
   [ -f "$1" ] ||  echo >&2 ERROR: The input file does not exists. ; exit 1; 
   TMPIN=$(mktemp)
   # Remove blank lines and delete duplicates 
   sed '/^$/d' "$1"| sort -g | uniq > "$TMPIN"

   NOW=$(date +"%Y-%m-%d-%X")
   LOGFILE="AMU-log-$NOW.log"

   for user in $(more "$TMPIN"); do
      # Checks if the user already exists.
      cut -d: -f1 /etc/passwd | grep "$user" > /dev/null
      OUT=$?
      if [ $OUT -eq 0 ];then
         echo >&2 "ERROR: User account: \"$user\" already exists."
         echo >&2 "ERROR: User account: \"$user\" already exists." >> "$LOGFILE"
      else
         # Create a new user
         /usr/sbin/useradd -d "$PERS_HOME""$user" -s "$PERS_SH" -m "$user"
         # passwdgen must be installed
         pass=$(passwdgen -paq --length 8)
         echo $pass | passwd --stdin $user
         # save user and password in a file
         echo -e $user"\t"$pass >> "$LOGFILE"
         echo "The user \"$user\" has been created and has the password: $pass"
      fi
   done
   rm -f "$TMPIN"
   exit 0
else
   echo >&2 "ERROR: You must be a root user to execute this script."
   exit 1
fi

============

希望这会有所帮助。

干杯, 卡雷尔

【讨论】:

【参考方案14】:

Tralemonkey 的解决方案几乎也对我有用……但并不完全。我最终这样做了:

echo -n '$#@password@#$' | passwd myusername --stdin

他的解决方案没有包含 2 个关键细节,-n 阻止 echo 将 \n 添加到正在加密的密码中,并且单引号保护内容不被 shell (bash) 解释我的情况。

顺便说一句,我在 CentOS 5.6 系统上以 root 身份运行此命令,以防有人想知道。

【讨论】:

不错,不知道其他人如何设法让它与换行符一起工作。【参考方案15】:

适用于 Debian 和 Red Hat 的解决方案。取决于 perl,使用 sha-512 哈希:

cat userpassadd
    #!/usr/bin/env bash

    salt=$(cat /dev/urandom | tr -dc A-Za-z0-9/_- | head -c16)
    useradd -p $(perl -e "print crypt('$2', '\$6\$' . '$salt' . '\$')") $1

用法:

userpassadd jim jimslongpassword

它可以有效地用作单线,但您必须自己在正确的位置指定密码、盐和用户名:

useradd -p $(perl -e "print crypt('pass', '\$6\$salt\$')") username

【讨论】:

【参考方案16】:

来自 IBM (https://www.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.cmds1/chpasswd.htm):

创建一个文本文件,例如 text.txt 并使用用户:密码对填充它,如下所示:

user1:password1
user2:password2
...
usern:passwordn

保存 text.txt 文件,然后运行

cat text.txt | chpassword

就是这样。该解决方案是 (a) 可扩展的,并且 (b) 不涉及在命令行上打印密码。

【讨论】:

【参考方案17】:
 echo $password; echo $password;  | passwd $username 

【讨论】:

虽然理论上这可以回答这个问题,但it would be preferable 在这里包含了答案的基本部分。【参考方案18】:

对于 RedHat / CentOS,这是创建用户、添加密码并使用户成为 sudoer 的代码:

#!/bin/sh
echo -n "Enter username: "
read uname

echo -n "Enter password: "
read -s passwd

adduser "$uname"
echo $uname:$passwd | sudo chpasswd

gpasswd wheel -a $uname

【讨论】:

【参考方案19】:

用法:./my_add_user.sh USER PASSWD

代码:

#!/bin/bash
# my_add_user.sh

if [ "$#" -lt 2 ] 
 then
       echo "$0 username passwd"
       exit
fi

user=$1
passwd=$2

useradd $user -d /data/home/$user  -m  ;
echo $passwd | passwd $user --stdin;

【讨论】:

以上是关于如何使用 Bash 脚本自动添加用户帐户和密码?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用busybox 和openssl 在脚本中更改用户密码?

从 bash 脚本添加 ssh-add 并自动输入密码

bash 脚本从 bash 脚本添加 git 凭据

Linux基础7-2 Bash脚本编程练习1

Linux基础7-2 Bash脚本编程练习1

bash脚本练习