从bash中的while循环返回变量

时间:2019-06-21 22:14:14

标签: bash while-loop

我正在尝试使用while循环在用户注册期间反复提示输入用户名,直到提供了有效的用户名为止(即尚未声明用户名)。

不幸的是,我现在仅用bash进行编码不到70个小时,所以我对如何执行此操作并不熟悉。我最初的想法是,如果用户名存在问题,则像在Windows批处理脚本中一样使用“ goto”,但是显然这不是bash中的问题,并且循环似乎是推荐的方法。我对bash中的循环并不熟悉,因此我做了一些研究,直到我在SO上找到了一个很好的答案。这不是确切的帖子(我现在找不到),但是我在看问题like this one

结果代码如下:

echo -e "Now, choose a unique username. No special characters, please."
uniqueuser=0 # Assume a valid username has not been chosen from the get-go
while [ "$uniqueuser" == "0" ]
do
    read -p "Username: " username
    lusername=`echo $username | sed y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/` #lowercase username
    if [ "$lusername" == "admin" ] || [ "$lusername" == "administrator" ] || [ "$lusername" == "npstn" ] || [ "$lusername" == "phreak" ] || [ "$lusername" == "guest" ] || [ "$lusername" == "user" ] || [ "$lusername" == "sysop" ]
    then
        echo -e "That username is reserved. Please pick another username."
    else
        username=`php /home/com/encode.php "$username"`
        available=`curl "https://example.com/redacted/redacted.php?key=$key&type=checkusername&username=$username" --silent`
        if [ "$available" == "1" ]
        then
            uniqueuser=$((1)) # Username is unique and acceptable
        else
            echo -e "That username is taken. Please choose another one."
        fi
    fi
done <input.data # so that username variable persists outside of while loop
echo -e "That username is available... or was... now, it's yours!"
echo -e "On this board, we have no annoying password length or complexity requirements. That said, your password cannot be null, nor can it use the plus symbol. Choose wisely!"

当到达外壳脚本的这一部分时,我看到:

Now, choose a unique username. No special characters, please.
/home/com/redacted.sh: line 4: input.data: No such file or directory
That username is available... or was... now, it's yours!
On this board, we have no annoying password length or complexity requirements. That said, your password cannot be null, nor can it use the plus symbol. Choose wisely!

使用“ input.data”的原因是将$ username变量从子shell中取出并返回到主shell中。但是,这似乎导致了错误。我该如何解决?

1 个答案:

答案 0 :(得分:3)

您误读了您所依赖的来源。从文件中重定向标准输入,如:

count=0
while IFS= read -r line; do
  (( ++count )) # or do something else
done < input.data
echo "$count"   # will print number of lines in the file input.data

仅在替代方法是从管道重定向标准输入时阻止创建子外壳。例如,您确实会丢失在以下位置设置的变量的内容:

# DO NOT DO THIS; this is the practice the other answers were teaching how to avoid.
count=0
cat input.data | while IFS= read -r line; do
  (( ++count )) # or otherwise modify data within the loop
done
echo "$count"   # will print 0, because the loop was in a subshell

当您从stdin输入而不是从文件输入时,此更改不是必需的,也是不适当的。

问题是cat input.data |< input.data是替代问题。如果您的原始代码中没有cat input.data |,则无需使用< input.data来替换它。


证明while read循环可以从标准输入中读取并保留其变量的值,而无需任何此类重定向:

count=0
prompt='Enter a string, or a blank line to stop: '
while IFS= read -r -p "$prompt" line && [[ $line ]]; do
  (( ++count ))
  printf 'Line %d: %s\n' "$count" "$line"
done
echo "Final counter is $count"

...当输入空白行时,将$count的相同值保留在循环外,将其递入循环内