【问题标题】:My bash script gets into infinite loop我的 bash 脚本进入无限循环
【发布时间】:2016-01-25 14:45:56
【问题描述】:

我想从文件中读取存储库名称,显示 YES-NO-CANCEL 对话框,然后如果用户回答“是”则添加存储库。到目前为止,我已经写了这段代码:

g_dlg_yes=1
g_dlg_no=0
g_dlg_cancel=127

show_confirm_dlg()
{
    local prompt="$* [y(es)/n(o)/c(ancel)]: "
    local resp=""
    while [ "$resp" != "y" ] && [ "$resp" != "n" ] && [ "$resp" != "c" ]; do
        echo "$prompt"
        read resp
    done
    if [ "$resp" = "y" ]; then
        g_dlg_res=$g_dlg_yes
    elif [ "$resp" = "n" ]; then
        g_dlg_res=$g_dlg_no
    elif [ "$resp" = "c" ]; then
        g_dlg_res=$g_dlg_cancel
    else
        g_dlg_res=$g_dlg_cancel
    fi
}

add_repo()
{
    local filename="/home/stojan/repo.list"
    while read -r line
    do
        local repo_name=$line
        echo "Name read from file - $line"
        show_confirm_dlg "Add repository $repo_name?"
        local rc=$g_dlg_res
        if [ $rc -eq $g_dlg_yes ]; then
            add-apt-repository -y $repo_name
            ##echo $repo_name
        elif [ $rc -eq $g_dlg_no ]; then
            echo "Repository $repo_name rejected"
        elif [ $rc -eq $g_dlg_cancel ]; then
            echo "Script cancelled"
            exit 1
        else
            echo "Unknown response. Now cancelling..."
            exit 1
        fi
        echo "Press ENTER..."
        read _

    done < "$filename"
}

add_repo

问题是当我运行这个脚本时,我卡在show_confirm_dlg() 并进入无限循环。那就是脚本不会等待我的输入,而是一遍又一遍地重复确认。

【问题讨论】:

  • 如何运行脚本?那里有任何重定向/管道吗?此外,显示的代码只是声明了函数,它不运行任何东西。
  • 哦,对不起。复制/粘贴错误。我编辑了我的代码。

标签: bash loops


【解决方案1】:

使用read 从标准输入读取。当您在重定向中使用 read 时,它不会从键盘读取,而是从当时的任何标准输入读取。

参考:

{
    read a
    echo $a
} < <(echo Hello)

您可以在其他地方复制标准输入,以便同时处理多个流:

exec 3<&0          # fd3 now points to the initial stdin
{
    read a         # This reads the "Hello".
    read b <&3     # This reads from the keyboard.
    echo "$a, $b"

} < <(echo Hello)
exec 3<&-          # Close the fd3.

【讨论】:

  • 换句话说,只有一个“标准输入”。如果您想在通过终端上的用户交互控制读取方式的同时从文件中读取数据,则必须使用两个不同的输入流(而不是通过标准输入 (&lt;) 引入文件)。
  • 太棒了!我明白了!
  • 有什么理由不只使用 u1 而不是 exec ?
  • @123:已更新。从标准输出中读取似乎很奇怪。
【解决方案2】:

要从while...do 循环中获取用户输入,您还可以这样做:

while [ "$resp" != "y" ] && [ "$resp" != "n" ] && [ "$resp" != "c" ]; do
    echo "$prompt"
    read resp </dev/tty
done

请参考这个帖子: Read input in bash inside a while loop

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-16
    相关资源
    最近更新 更多