我正在尝试为我的脚本创建一个非常简单的登录控制台,这只是为了好玩,看看它是否有效。
基本上,我认为可能的情况是这样的。
如果存在某种模式,我将读取文件$password_file
和文件$username_file
。假设我在两个文件的第一行(或任何行)中都输入了“bryan”。现在我想在脚本继续执行其基本功能之前放置这段代码。
echo "Welcome"
echo "Ur username is:"
read username
echo "Ur password is:"
read password
if sed -n "/$username/" $username_file; then
if sed -n "/$password" $password_file; then
else
exit;
fi
fi
我想我在这里做错了什么,因为我收到一个错误,在附近有一个意外的标记else
。
所以基本上我只希望 if 语句首先读取$username_file
,然后如果模式bryan
在该文件中,我希望它读取$password_file
,之后我希望脚本继续转到我编写的正常脚本开始的某一行。
我希望我解释得正确,以便你能理解我。
(我还可以通过添加类似的内容来扩展这个小脚本,如果用户名或密码不在该文件中,则回显“未找到,脚本将重新加载再试一次”。)
答案1
问题是 bash 将其解释为;在该行中then; else
放入一个。:
如果每行仅由您要查找的内容组成,您也可以使用fgrep -x
:
echo "Welcome"
echo "Username:"
read username
echo "Password:"
read password
if ! (fgrep -qx "$username" $username_file && fgrep -qx "$password" $password_file); then
exit
fi
答案2
这里存在一些问题:
then
内部语句的部分中没有命令if
,这导致了您看到的错误。您可以通过:
在该then
部分中使用占位符伪命令或否定测试并省略该else
部分来解决此问题。该
sed
命令也是无效的,而且它无论如何都不是适合这项工作的工具。在文件中搜索特定行grep
通常是首选命令。在这种情况下,grep -Fx
执行纯文本 (-F
) 整行 (-x
) 匹配可能是最好的选择。if ... if ... else 逻辑也关闭了。我假设您想在未找到用户名或密码时退出,但(如所写)该
else
子句仅在用户名曾是成立,和密码不对。要修复此问题,请使用如下方法:if ! grep -Fxq "$username" "$username_file" || ! grep -Fxq "$password" "$password_file"; then echo "Invalid login" exit 1 fi
或者可能:
if ! grep -Fxq "$username" "$username_file"; then echo "User $username not found" exit 1 elif ! grep -Fxq "$password" "$password_file"; then echo "Incorrect password" exit 1 fi
实际上,这种逻辑仍然是错误的;它只检查用户名和密码是否存在于各自的文件中,而不是检查它们是否在一起。我可以输入我的密码和别人的用户名,它就会让我进入。您需要确保用户名和密码在一起,可能只需将它们放在同一个文件中并同时搜索它们即可:
if ! grep -Fxq "$username:$password" "$user_file" ; then echo "Invalid login" exit 1 fi
最后,存储密码(即使是在只有 root 可以读取的文件中)是一个非常糟糕的主意——对密码进行哈希处理并存储哈希值。实际上,为了获得最佳安全性,您应该使用加盐哈希,这会使搜索变得复杂——您必须找到用户条目,找出与其密码一起使用的盐,使用相同的盐对用户输入的内容进行哈希处理,然后将其与文件中的内容进行比较。这反过来意味着它将
grep -Fx
不再起作用,我们需要grep
在进行模式匹配的模式下使用,并小心避免用户名中的模式元字符......
假设您有 openssl 可用,下面是一个简单的尝试:
echo "Welcome"
read -p "Ur username is: " username
if [[ "$username" =~ "[][(){}*.?+|^\$]" ]]; then
echo "Illegal character in username"
exit 1
fi
# Find the user's record in the file
user_record="$(grep "^$username:" "$user_file")"
if [[ -z "$user_record" ]]; then
echo "User $username not found"
exit 1
fi
# Parse out the user's hashed password and salt
recordedhash="${user_record#*:}"
if [[ "$recordedhash" != '$1$'* ]]; then
echo "Invalid user record for $username"
exit 1
fi
salt="${recordedhash#\$1\$}"
salt="${salt%\$*}"
read -p "Ur password is: " -s password
echo
if [[ "$(printf "%s" "$password" | openssl passwd -1 -stdin -salt "$salt")" != "$recordedhash" ]]; then
echo "Incorrect password"
exit 1
fi
要在用户文件中创建条目,请使用以下命令:
read -p "Ur username is: " username
if [[ "$username" =~ "[][(){}*.?+|^\$]" ]]; then
echo "Illegal character in username"
exit 1
fi
read -p "Ur password is: " -s password
echo
hashedpw="$(printf "%s" "$password" | openssl passwd -1 -stdin)"
user_record="$username:$hashedpw"
# Then do something to add $user_record to the file, or replace the existing record if there is one
我不保证上述内容没有错误;我只是对其进行了一些非常基本的测试。