【问题标题】:File input getting consumed inside the while loop在 while 循环中消耗文件输入
【发布时间】: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 ] 工具,它可以帮助您轻松识别小错误。

标签: bash while-loop


【解决方案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"

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

【讨论】:

  • 不敢相信我错过了。找到它比编写脚本本身需要更长的时间。感谢您指出这一点并提供最佳做法!
猜你喜欢
  • 2012-07-20
  • 2016-04-26
  • 1970-01-01
  • 2017-10-12
  • 2013-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-16
相关资源
最近更新 更多