AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 496881
Accepted
Kes
Kes
Asked: 2019-01-27 05:52:25 +0800 CST2019-01-27 05:52:25 +0800 CST 2019-01-27 05:52:25 +0800 CST

使用任何特定键终止包含长时间睡眠和其他内容的 BASH For 循环

  • 772

我有一个 bash 脚本

  • 有一个 for 循环,它迭代很多次并在迭代之间休眠,可能会持续很长时间。那么它

  • 将结果写入文件,然后终止。

有时我会在许多循环迭代完成之前得到我需要的结果。

在这些情况下,我需要脚本break退出 for 循环,而它要么是

  • 做事,或

  • 睡眠

这样它将继续执行脚本的其余部分,在 for 循环之后,它正在编写迄今为止收集的数据的报告文件。

我希望使用组合键,例如 CTRL+Q,break退出 for 循环。

脚本如下所示:

#!/bin/bash

for (( c=0; c<=$1; c++ ))
do  

# SOME STUFF HERE
#  data gathering into arrays and other commands here etc

# sleep potentially for a long time
sleep $2

done

#WRITE REPORT OUT TO SCREEN AND FILE HERE
bash shell-script
  • 3 3 个回答
  • 1554 Views

3 个回答

  • Voted
  1. Best Answer
    user147505
    2019-01-27T06:18:17+08:002019-01-27T06:18:17+08:00

    我有一段时间没有接触过这类任务,但我记得曾经有这样的事情:

    #!/bin/bash
    
    trap break INT
    
    for (( c=0; c<=$1; c++ ))
    do  
    
    # SOME STUFF HERE
    #  data gathering into arrays and other commands here etc
    
        echo loop "$c" before sleep
    
        # sleep potentially for a long time
        sleep "$2"
    
        echo loop "$c" after sleep
    
    done
    
    #WRITE REPORT OUT TO SCREEN AND FILE HERE
    
    echo outside
    

    这个想法是使用Ctrl-C来打破循环。这个信号(SIGINT)被陷阱捕获,它打破循环并让脚本的其余部分跟随。

    例子:

    $ ./s 3 1
    loop 0 before sleep
    loop 0 after sleep
    loop 1 before sleep
    ^Coutside
    

    如果您对此有任何问题,请告诉我。

    • 6
  2. ilkkachu
    2019-01-27T06:21:00+08:002019-01-27T06:21:00+08:00

    最简单的方法是使用Ctrl+C,因为默认情况下它会发出INT信号,这会导致大多数应用程序停止,您可以在 shell 中捕获它。

    要一次中断整个循环,您可以在子shell 中运行它,并exit在中断时运行它。在这里,陷阱仅设置在子shell中,并且只有它退出。

    #!/bin/bash
    
    (
    trap "echo interrupted.; exit 0" INT
    while true; do
            echo "running some task..."
            some heavy task 
            echo "running sleep..."
            sleep 5;
            echo "iteration end."
    done
    )
    
    echo "script end."
    
    • 5
  3. sudodus
    2019-01-27T06:52:11+08:002019-01-27T06:52:11+08:00

    在某些情况下,最好有一个不中断“这里的一些东西”的解决方案,并且只在 shellscript 等待时中断。

    然后,您可以使用带有一些选项的 shell 内置命令read,而不是sleep.

    试试这个shellscript,

    #!/bin/bash
    
    echo "Press 'q' to quit the loop and write the report"
    echo "Press 'Enter' to hurry up (skip waiting this time)"
    
    for (( c=0; c<=$1; c++ ))
    do  
    
     echo "SOME STUFF HERE (pretending to work for 5 seconds) ..."
     sleep 5
     echo "Done some stuff"
    
    #  data gathering into arrays and other commands here etc
    
    # sleep potentially for a long time
    
    #sleep $2
     read -n1 -st$2 ans
     if [ "$ans" == "q" ]
     then
      break
     elif [ "$ans" != "" ]
     then
      read -n1 -st$2 ans
     fi
    done
    
    echo "WRITE REPORT OUT TO SCREEN AND FILE HERE"
    

    您可以找到有关read使用命令的详细信息help read,

          -n nchars return after reading NCHARS characters rather than waiting
                for a newline, but honor a delimiter if fewer than
                NCHARS characters are read before the delimiter
          -s    do not echo input coming from a terminal
          -t timeout    time out and return failure if a complete line of
                input is not read within TIMEOUT seconds.  The value of the
                TMOUT variable is the default timeout.  TIMEOUT may be a
                fractional number.  If TIMEOUT is 0, read returns
                immediately, without trying to read any data, returning
                success only if input is available on the specified
                file descriptor.  The exit status is greater than 128
                if the timeout is exceeded
    
    • 2

相关问题

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • MySQL Select with function IN () with bash array

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve