在 while 循环中消耗文件输入

Posted

技术标签:

【中文标题】在 while 循环中消耗文件输入【英文标题】:File input getting consumed inside the while loop 【发布时间】:2016-07-30 01:39:59 【问题描述】:

我正在阅读一个查找文件并为文件中的每一行执行一组操作。然而,while 循环只读取文件中的第一行并退出。这是我拥有的当前代码。

sql_from_lkp $lookup

function sql_from_lkp 
    lkp=$1
    while read line; do
        sql_from_columns $line
        echo $line
    done < $lkp


function sql_from_columns 
    table_name=$1
    table_column_info_file=$table_name_columns
    line_count=`cat $table_info_file | wc -l`
    ....

通过选择性地注释代码,我发现如果我注释line_count 行,while 循环会遍历文件中的每一行并且工作正常。所以输入被cat 语句消耗掉了。

我已经检查了其他答案并了解到ssh 通常会在不使用 -n 选项的情况下消耗while 循环中的文件输入。但不知道如何解决这种情况。需要一些帮助。

【问题讨论】:

顺便说一句:您应该双引号引用所有变量引用,以免变量值受到分词和通配符的影响;此外,Bash 不允许您在定义之前调用函数。 乍一看,您似乎正在将line 传递给sql_from_colums,它期望table_name 作为输入? @David 我基本上每一行都有一个表格。我重构了代码并删除了很多细节,使场景更容易出现。 @Vinay :还建议使用[ shell_check ] 工具,它可以帮助您轻松识别小错误。 【参考方案1】:

您打错了变量名:$table_info_file 应该是 $table_column_info_file

如果你改正了,你的问题就会消失。


通过引用一个不存在的变量——输入错误的$table_info_file——你实际上是在sql_from_columns()中执行cat | wc -l(没有传递给cat的文件名参数),这使得cat标准输入

因此 - 在阅读了 while 循环中的 1st 行之后 - sql_from_columns() 中的 cat 命令消耗整个其余部分您的输入(@ 987654333@),这就是 while 循环在第一次迭代后退出的原因。


一般来说,

您应该双引号引用所有变量引用,以免它们的值受制于word-splitting and globbing。

Bash 不允许您在定义之前调用函数,因此如您的问题中所述,您的代码从根本上说无法工作。

虽然仍然支持用于命令替换的旧版 `...` 语法,但它具有 pitfalls that can be avoided with the modern $(...) syntax。

一种更有效的计算行数的方法是将输入文件通过&lt; 传递给wc -l,而不是通过cat 和管道(wc 也接受文件名操作数直接,但它会在计数后打印输入文件名)。

顺便说一句,如果你这样做了,你可能会更容易发现你输入错误的变量引用,因为在 &lt; 后面没有文件名的情况下,Bash 会报告 ambiguous redirect 错误。

以下是解决所有问题的重新表述:

function sql_from_lkp 
    lkp=$1
    while read line; do
        sql_from_columns "$line"
        echo "$line"
    done < "$lkp"


function sql_from_columns 
    table_name=$1
    table_column_info_file=$table_name_columns
    line_count=$(wc -l < "$table_column_info_file")
    # ...


sql_from_lkp "$lookup"

请注意,我只在严格需要使命令健壮的地方添加了双引号;每当引用参数(变量)时添加它们不会有什么坏处。

【讨论】:

不敢相信我错过了。找到它比编写脚本本身需要更长的时间。感谢您指出这一点并提供最佳做法!

以上是关于在 while 循环中消耗文件输入的主要内容,如果未能解决你的问题,请参考以下文章

在while循环中输入Cin

为啥我的 while 循环被激活,但没有其他反应?

输入在 do-while 循环中无法与 Scanner 类一起使用

在使用读取(bash)的while循环中禁用用户输入

在一个函数中以两个不同的while循环输入不起作用

python的用户输入和while循环