如何在 bash/linux 脚本中执行相同的循环 1 小时?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8168428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 01:27:06  来源:igfitidea点击:

How to execute the same loop for 1 hour in bash/ linux scripting?

linuxbashshell

提问by Frost

I want to open and close some web pages with random intervals for an hour.

我想以一个小时的随机间隔打开和关闭一些网页。

So far i have written the innards

到目前为止,我已经写了内脏

FILE=webpages
TIMES=0
while test $TIMES -lt 10
do
    #Picks random line(Website) from FILE
    TEMPWEB=`shuf -n 1 $FILE`
    echo "Opening" $TEMPWEB
    #Opens TEMPWEB
    xdg-open $TEMPWEB
    sleep 10
    #Kills firefox
    ps -e | grep firefox | sed 's/\(.[0-9]*\).*//' | xargs kill
    TIMES=$(($TIMES+1))
done

So I'm am missing the while condition.
I want something like:

所以我错过了 while 条件。
我想要这样的东西:

TIMER = 0h 0m 0s
while( TIMER < 1 h)
   ....
done

Is this possible?

这可能吗?

PS. what's the command to random number?

附注。随机数的命令是什么?

采纳答案by thiton

Surely. Try:

一定。尝试:

#!/bin/bash
START=`date +%s`
while [ $(( $(date +%s) - 3600 )) -lt $START ]; do
    ....
done

date +%sshows the current time in seconds since 1970. The loop computes the current date of an hour ago and checks if it exceeds the start time.

date +%s显示自 1970 年以来的当前时间(以秒为单位)。循环计算一小时前的当前日期并检查它是否超过开始时间。

回答by Chris J

One way you can do this is with signals and traps. Here's a simple example:

一种方法是使用信号和陷阱。这是一个简单的例子:

#!/bin/bash

me=$$

# Start a background process to signal us when the time has passed
(
        sleep 10
        kill -USR1 $me
) &

# When we recieve SIGUSR1, commit suicide
trap "kill $me" SIGUSR1

# Do stuff until we commit suicide
while [ 1 -eq 1 ]
do
        echo 'Hello!'
        sleep 1
done

The comments are self-explanetory (I hope). The first part kicks off a background process that just sleeps for a period of time (10 seconds in this example), and then when it wakes up sends SIGUSR1 to the originating process.

评论是不言自明的(我希望)。第一部分启动一个只休眠一段时间(在本例中为 10 秒)的后台进程,然后在它醒来时将 SIGUSR1 发送到原始进程。

The shellscript catches this (with trap) and just issues a killto its own PID, stopping the process.

shellscript 捕捉到这个(用trap)并且只是kill向它自己的 PID发出 a ,停止进程。

The rest of it is just an infinite loop -- it's the trapthat kills the script and terminates the loop.

其余的只是一个无限循环——它trap是杀死脚本并终止循环的。

Technically you don't need the trap in the example above: the background process could just issue kill $medirectly, but I've included it for completeness as you can use it as a hook to do other things (e.g., if you don't want to die but set a flag and have the loop terminate naturally, or you have some clean-up to do before terminating).

从技术上讲,您不需要上面示例中的陷阱:后台进程可以直接发出kill $me,但为了完整起见,我将其包含在内,因为您可以将其用作挂钩来执行其他操作(例如,如果您不想死但设置一个标志并使循环自然终止,或者在终止之前您有一些清理工作要做)。

回答by Gilles Quenot

This is my solution :

这是我的解决方案:

#!/bin/bash

# function to display a number in a range
randrange() { echo $(( ( RANDOM % ( -  +1 ) ) +  )); }

# sleep 1 hour and keep backgrounded PID in a variable
sleep 3600 & _suicide_pid=$!

# while the process is UP
while kill &>/dev/null -0 $_suicide_pid; do
    # ----->8--- do what you want here <---8<-----
    sleep $(randrange 10 15) # random sleep in 10-15 range
done