首先,您需要将参数引用到 echo 以避免字符串拆分和全局扩展:
echo "Password successfully changed for $USERNAME to $PASSWORD at `date`"
其次,如果您想以机器可解析的形式发出密码,请使用printf %q
:
printf 'Password successfully changed for %s to %q at %s\n' \
"$USERNAME" "$PASSWORD" "$(date)"
顺便说一句 - 对局部变量使用全大写名称是不好的做法(因为它有与内置变量和环境变量发生命名空间冲突的风险)。
一个完整版本的脚本,更强烈地尝试遵循脚本编写的最佳实践(但仍然严重未能遵循任何关于安全性的良好实践),看起来像这样:
#!/bin/bash
# you probably don't need to export PATH -- if something is already exported,
# it stays exported on updates.
PATH=/bin:/usr/bin:/sbin:/usr/sbin
## this is really, _really_ horrible "security".
myencpass='IURv34bmNocv98RnZXQhCg=='
mypass=$(base64 --decode <<<"$myencpass")
echo
echo "Enter username you'd like to change password for:"
read -r username
if ! dscl /LDAPv3/127.0.0.1 -read "/Users/$username" &>/dev/null; then
# This is bad practice -- assuming that the only error that can happen is
# the nonexistent-user case, and hiding any other error messages, means that
# the user can't diagnose the _actual_ cause of any other error.
printf '\n\033[31m Username %s does not exist! Exiting...\033[0m\n' "$username"
exit 1
fi
printf '\nEnter New Password for %s\n' "$username"
read -r password
if dscl -u diradmin -P "$mypass" /LDAPv3/127.0.0.1 passwd "/Users/$username" "$password"; then
# previously, there was no conditional here, so we logged that this was
# successful even if it failed.
# And, of course, storing users' plaintext passwords in a log makes you evil.
printf "Password successfully changed for %s to %q at %s\n" \
"$username" "$password" "$(date)" \
| tee -a /var/log/odpasswd.log
fi
如果您想以正确的方式实际执行此操作,而不是尝试这种混淆技术,您将使用缓存的 Kerberos 票证对 LDAP 进行身份验证(我假设这是 MacOS 的开放目录——它可以做到这一点) , 只能由运行脚本的用户读取,并使用 sudo 允许临时权限升级到仅在运行此脚本时才能读取票证的用户。