【问题标题】:Idiomatic way to exit ksh while loop在循环中退出 ksh 的惯用方式
【发布时间】:2011-12-12 17:35:48
【问题描述】:

我有以下 5 秒计时器,它每秒打印一个星号。

timer () {
  i=1
  trap 'i=5' INT

  while [[ $i -le 5 ]]; do
    sleep 1
    printf "*"
    ((i+=1))
  done
}

不知何故,陷阱块似乎有点骇人听闻,我想知道是否有更正确的方法来中断整个循环(不仅仅是当前的睡眠周期)。我试过了:

trap 'print "foo"' INT

在函数内部和外部的不同位置,但正如我之前提到的,这只会中断当前的睡眠周期。

【问题讨论】:

    标签: shell while-loop ksh shell-trap


    【解决方案1】:

    也许我错过了什么,但有什么问题:

    timer() {
      i=0
      while (( ++i <= 5 )); do
        sleep 1
        printf '*'
      done
    }
    

    【讨论】:

    • 感谢您的回复。我认为您没有解决我问题的陷阱部分。无论我如何执行循环,我都使用陷阱来跳出循环(但不是周围的脚本,为简单起见,此处未显示)。但是你的循环建议看起来比我的好。
    • 嗨,@amorphousone!如果您需要在收到 sigint 时将 i 设置为 5,那么您已经使用了正确的代码(但我怀疑您是否真的需要这个)。如果您需要提前中断循环(即由于某种原因在 while 条件评估为 false 之前),您需要使用 break 命令。
    • 感谢您的建议。我知道中断,但中断条件仍将依赖于用户输入(ctl-c)。在后台读取用户输入时如何保持循环? (我为此搜索了很多)。
    • 嗨@amorphousone,我不确定我理解您所说的“依赖用户输入”是什么意思。就您的第二个问题而言,您可以在后台运行循环并读取用户输入在前台。
    【解决方案2】:

    这在 bash 中对我有用:

    #!/bin/bash
    
    function timer {
    
        trap "break" INT
    
        i=0
        while (( ++i <= 5 )); do
            sleep 1
            printf '*'
        done
    }
    
    echo "Starting timer"
    timer
    
    echo "Exited timer"
    echo "Doing other stuff...."
    

    这在 ksh 中(注意陷阱语句的不同位置):

    #!/bin/ksh
    
    function timer {
    
        trap "break" INT
    
        i=0
        while (( ++i <= 5 )); do
            sleep 1
            printf '*'
        done
    }
    
    echo "Starting timer"
    timer
    
    echo "Exited timer"
    echo "Doing other stuff...."
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-05
      • 2011-09-25
      • 1970-01-01
      • 1970-01-01
      • 2016-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多