2

我正在制作一个从文件中获取输入的循环,以确定是否允许用户使用特定程序。

#!/bin/bash

boole=false

echo "Username: "
read username

echo "debug0"

for((line=1; $boole=false; line++)); do
    echo "debug.5"
    auth=`head -n $line users | tail -n $line`

    echo "debug1"

    if [ $username = $auth ]; then
        echo "debug2"
        echo "authentication success"
        read
        exit 0
    fi

    if [ $auth = "#end" ]; then
        echo "debug3"
        echo "authentication failed"
        read
        exit 0
    fi
done

echo "skip everything"

输出是

Username:
admin
debug0
skip everything

与用户的文件有

root
admin
...
#end

#end并且boole应该告诉循环结束

这只是调试阶段,所以它实际上并没有执行任何程序,它只是应该告诉我是否允许用户使用它。

4

3 回答 3

0

bash 中的循环与 C 循环不同。基本语法是:

for arg in [list]
do 
    [command(s)...]
done

但是,有一种 C 风格的语法,就像您正在使用的那样:

for ((x=1; x<=3; x++))
{
    echo $x
}

如评论中所述,当您在双括号内写入时,$boole=false在处理双括号的内容之前$boole被取消引用,因此变为. 此外,当您将某些内容括在双括号中时,您应该使用它进行比较。在任何情况下,无论是还是,它们都为真,因为第一个成功分配给,而第二个为真,因为 a为真。false=false==$boole=false$boole==falsefalsefalsefalse==false

无论如何,在你的情况下,我可能会使用一个 while 循环。这是一个例子:

bool=true
int=1
while $bool; do
    echo $int
    (( int++ ))
    if [[ $int == 10 ]]; then
        bool=false
    fi
done
echo $int
于 2013-06-10T19:16:45.670 回答
0

读取文件时使用 while 循环,而不是 for 循环。这记录在http://mywiki.wooledge.org/BashFAQ/001

while read -r line; do
  something_with "$line"
done

在这种情况下,您可以使用关联数组来存储授权用户列表:

declare -A authorized_users=()
while read -r username; do
  authorized_users[$username]=1
done <input_file

...然后您可以检查用户是否在该列表中,如下所示:

if [[ ${authorized_users[$possible_username]} ]]; then
  echo "User is authorized!"
fi

请注意,在 bash 4 中添加了关联数组语法。

于 2013-06-10T19:23:42.963 回答
0

我已尝试为您清除它..您可能希望查看一些逻辑,因为如果它有任何其他用户,它只会返回最后一个跳过所有内容..无论如何..

有一些问题要问,因为如果您正在循环输入,那么在您正在退出的 for 循环中,它会结束输入,不确定您正在尝试实现什么,因为它代表 for 循环的唯一用途是用户输入用户作为空格分隔列表的第一个输出 - 它的设计目的不是继续向用户返回提示...

所以我更新了脚本以循环并询问用户输入是否匹配失败列表:

(很抱歉,如果现在与您想要的相差甚远 - 我认为它可能更像您想要的?)

#!/bin/bash


echo "debug0"
i=0;

#Maybe you want something to measure bad input
# right now only if user puts in #end 3 times will this pass
# so again look at the logics if needed add the attempts++ to skip everything..
max_attempts=3;

# current running attempts set as 0;
attempts=0;



#start function repeats for user input
function start() { 
     echo "Username: "
     read input
     # run process input function
     process_input
}

# The process input function works out what user has put in
function process_input()  { 
   # Go through for loop of users command
    loggedin=$(users);
   for auth in ${loggedin[@]}; do
       echo "debug.5"
       echo "debug1"
       # if current value from users output matches the user input
       if [[ $auth == $input ]]; then
        echo "debug2"
        echo "authentication success"
        #unsure what you are reading here since your not asking for a prompt
        read;
        exit 0;
        # either if input matches #end or anything after 3 attempts that 
        # does not match admin
        elif [[ $auth == "#end" ]] || [[ $attempts -gt $max_attempts ]]; then

        echo "debug3"
         echo "authentication failed - failed attempts $attempts "
        ((attempts++))

        start;
      fi
done

echo "skip everything"
# removed comment from start function below if you want to get user to re-enter 
start;

}

# begin your program by running the start function
start;
于 2013-06-10T19:36:17.417 回答