expect 不会在 bash 脚本中将输入传递给 passwd
expect doesn't pass input to passwd in bash script
我正在尝试使用 expect 将 $PASSWORD 变量内容传递给 passwd。这似乎有效,添加了用户,但是一旦您尝试通过 ssh 与其中一个用户登录,它就不起作用了。如果我手动设置密码,那就没问题了。
以前有人遇到过这个问题吗?
USERS=(user1 user2 user3)
generatePassword ()
{
pwgen 16 -N 1
}
# Check if user is root
if [ $(whoami) != 'root' ]; then
echo "Must be root to run [=11=]"
exit 1;
fi
# Check if pwgen is installed:
if [[ $(dpkg -s pwgen > /dev/null 2>&1; echo ${PIPESTATUS} ) != '0' ]]; then
echo -e "pwgen is not installed, this script will not work without it\n\n'apt-get install pwgen'\n"
exit 1;
else
echo -e "Starting Script...\n\n"
fi
# Iterate through users and add them with a password
for i in ${USERS[@]}; do
PASSWORD=$(generatePassword)
echo "$i $PASSWORD" >> passwords
useradd -m "${i}"
echo -e "Adding $i with a password of '$PASSWORD'\n"
expect -c "
spawn passwd ${i}
expect \"Enter new UNIX password:\"
send -- \"$PASSWORD\r\"
send -- \"\r\"
expect \"Retype new UNIX password:\"
send -- \"$PASSWORD\r\"
send -- \"\r\"
"
echo -e "\nADDED $i with a password of '$PASSWORD'\n"
done
首先:最直接的问题是当您键入 \r
时,您没有转义反斜杠文字,所以这些只是在 expect
侧变成了 r
s ;似乎可以解决问题的最小可能更改是将它们更改为 \r
.
但是 -- 不要那样做:在 expect
中,与其他语言一样,字符串应作为文字传递,而不是代入代码。
expect -f <(printf '%s\n' '
set username [lindex $argv 0];
set password [lindex $argv 1];
spawn passwd $username
expect "Enter new UNIX password:"
send -- "$password\r"
send -- "\r"
expect "Retype new UNIX password:"
send -- "$password\r"
send -- "\r"
') -- "$i" "$PASSWORD"
您还可以将有问题的文字文本保存到文件中,运行 expect -f passwd.expect -- "$i" "$PASSWORD"
也同样有效(并避免依赖 <()
语法,即bash).
采用的 ksh 扩展
您根本不需要 expect:使用 chpasswd
而不是 passwd
#!/bin/bash
users=(user1 user2 user3)
# Check if user is root
if [[ "$(id -un)" != 'root' ]]; then
echo "Must be root to run [=10=]"
exit 1
fi
# Check if pwgen is installed:
if ! dpkg -s pwgen > /dev/null 2>&1; then
printf "pwgen is not installed, this script will not work without it\n\n'apt-get install pwgen'\n"
exit 1
else
printf "Starting Script...\n\n"
fi
# Iterate through users and create a password
passwords=()
for user in "${users[@]}"; do
useradd -m "$user"
password="$user:$(pwgen 16 -N 1)"
passwords+=("$password")
echo "Adding user '$user' with '$password'"
done
printf "%s\n" "${passwords[@]}" | chpasswd
我添加了几个必需的引号。
我简化了 dpkg 检查。
或者,也许更简单,newusers
自动执行 "useradd" 和 "passwd" 函数。
for user in "${users[@]}"; do
password="$user:$(pwgen 16 -N 1)"
password=${password//:/-} # replace all colon with hyphen
printf "%s:%s::::/home/%s:/bin/bash\n" "$user" "${password//:/-}" "$user"
done | newusers
不过我认为新用户不会从 /etc/skel 填充主目录。
我正在尝试使用 expect 将 $PASSWORD 变量内容传递给 passwd。这似乎有效,添加了用户,但是一旦您尝试通过 ssh 与其中一个用户登录,它就不起作用了。如果我手动设置密码,那就没问题了。
以前有人遇到过这个问题吗?
USERS=(user1 user2 user3)
generatePassword ()
{
pwgen 16 -N 1
}
# Check if user is root
if [ $(whoami) != 'root' ]; then
echo "Must be root to run [=11=]"
exit 1;
fi
# Check if pwgen is installed:
if [[ $(dpkg -s pwgen > /dev/null 2>&1; echo ${PIPESTATUS} ) != '0' ]]; then
echo -e "pwgen is not installed, this script will not work without it\n\n'apt-get install pwgen'\n"
exit 1;
else
echo -e "Starting Script...\n\n"
fi
# Iterate through users and add them with a password
for i in ${USERS[@]}; do
PASSWORD=$(generatePassword)
echo "$i $PASSWORD" >> passwords
useradd -m "${i}"
echo -e "Adding $i with a password of '$PASSWORD'\n"
expect -c "
spawn passwd ${i}
expect \"Enter new UNIX password:\"
send -- \"$PASSWORD\r\"
send -- \"\r\"
expect \"Retype new UNIX password:\"
send -- \"$PASSWORD\r\"
send -- \"\r\"
"
echo -e "\nADDED $i with a password of '$PASSWORD'\n"
done
首先:最直接的问题是当您键入 \r
时,您没有转义反斜杠文字,所以这些只是在 expect
侧变成了 r
s ;似乎可以解决问题的最小可能更改是将它们更改为 \r
.
但是 -- 不要那样做:在 expect
中,与其他语言一样,字符串应作为文字传递,而不是代入代码。
expect -f <(printf '%s\n' '
set username [lindex $argv 0];
set password [lindex $argv 1];
spawn passwd $username
expect "Enter new UNIX password:"
send -- "$password\r"
send -- "\r"
expect "Retype new UNIX password:"
send -- "$password\r"
send -- "\r"
') -- "$i" "$PASSWORD"
您还可以将有问题的文字文本保存到文件中,运行 expect -f passwd.expect -- "$i" "$PASSWORD"
也同样有效(并避免依赖 <()
语法,即bash).
您根本不需要 expect:使用 chpasswd
而不是 passwd
#!/bin/bash
users=(user1 user2 user3)
# Check if user is root
if [[ "$(id -un)" != 'root' ]]; then
echo "Must be root to run [=10=]"
exit 1
fi
# Check if pwgen is installed:
if ! dpkg -s pwgen > /dev/null 2>&1; then
printf "pwgen is not installed, this script will not work without it\n\n'apt-get install pwgen'\n"
exit 1
else
printf "Starting Script...\n\n"
fi
# Iterate through users and create a password
passwords=()
for user in "${users[@]}"; do
useradd -m "$user"
password="$user:$(pwgen 16 -N 1)"
passwords+=("$password")
echo "Adding user '$user' with '$password'"
done
printf "%s\n" "${passwords[@]}" | chpasswd
我添加了几个必需的引号。
我简化了 dpkg 检查。
或者,也许更简单,newusers
自动执行 "useradd" 和 "passwd" 函数。
for user in "${users[@]}"; do
password="$user:$(pwgen 16 -N 1)"
password=${password//:/-} # replace all colon with hyphen
printf "%s:%s::::/home/%s:/bin/bash\n" "$user" "${password//:/-}" "$user"
done | newusers
不过我认为新用户不会从 /etc/skel 填充主目录。