【问题标题】:breaking from infinite loop打破无限循环
【发布时间】:2013-03-08 02:14:39
【问题描述】:

我在 bash 中运行这个查询:

mkfifo resp
while true; do 
    sudo nc -l -p 80 < resp |
    (cat & echo -e "HTTP/1.1 200 OK\r\n\r\nhello :)" > resp) ||
    break; 
done

但是当我 Ctrl+C 时,什么都没有发生,并且终端锁定了。

为什么?我做错了什么?

【问题讨论】:

  • 不确定是否相关,但您要么需要用反斜杠结束循环体的前两行,要么将管道/或运算符移动到上一行的末尾。目前,您有 3 个单独的以换行符结尾的命令,而不是包含管道和 break 命令的列表。
  • nc 可以使用-l-p,但不能同时使用两者。你能描述一下这个程序应该做什么吗?
  • @chepner 这完全取决于 nc/netcat 的风格(BSD 与 linux)。经常需要相反​​的情况
  • 我在 Linux 和 BSD (Mac OS X) 系统的手册页中都看到了禁令。

标签: bash loops cat


【解决方案1】:

我无法在我的环境 (RHEL) 中重新创建它——CTRL-C 对我来说很好用。在你的终端锁定后,我会打开一个新的并使用strace -p 看看发生了什么。

不过,我认为命令设置通常存在一些问题。

首先是你在子shell中后台处理catDoing this makes the stdin of the cat command /dev/null,而不是 nc 的输出,您正在管道输入子外壳。您可以通过比较以下输出来查看差异:

#! /bin/bash
# doesn't print yay
while true; do
    echo yay |
    (cat & false) ||
    break
done

用这个:

#! /bin/bash
# does print yay
while true; do
    echo yay |
    (cat ; false) ||
    break
done

另外,我不清楚这是否是故意的,但循环的中断条件通常基于子shell的退出代码,而子shell的退出代码将是echo的退出代码,这将永远成功,因此循环通常是无限的。您可以通过用echo 替换上述之一中的false 来看到这一点:

#! /bin/bash
while true; do
    echo yay |
    (cat & echo test) ||
    break
done

而且,正如@chepner 所指出的,您对nc 的使用通常也是不正确的。根据其手册页:

-l      Used to specify that nc should listen for an incoming connection rather than initiate a connection to a remote host.  It is an error to use this option in conjunction with the -p, -s, or -z options.

这实际上导致您的nc 命令什么都不做(没有输出,只是坐在那里)。您可以通过在一个 shell 中以 root 身份运行 mkfifo resp ; nc -l -p 80 &lt; resp,然后在另一个 shell 中以 root 身份运行 echo -e "HTTP/1.1 200 OK\r\n\r\nhello :)" &gt; resp 来看到这一点。

希望这会有所帮助。

【讨论】:

  • 呵呵,我同意你的回答。显然,您为对细节的关注感到非常自豪,我尊重这一点。在过去的 20 分钟里,我一直在玩你给我的关于 bash 的顿悟。 pastebin.com/fntNgc1T
【解决方案2】:

我怀疑 sudo。您是否尝试过从脚本中删除 sudo 并 sudo 整个脚本?

您是否尝试过 ctrl-Z 和 ps a 来查看是什么阻碍了它?

【讨论】:

    猜你喜欢
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-21
    相关资源
    最近更新 更多