如何在每个时间间隔内重复执行命令,以便可以运行命令来检查或监视目录?

不需要脚本,我只需要在终端中执行一个简单的命令即可。

#1 楼

您可以使用watch命令,watch用于定期运行任何指定的命令。

打开终端并键入:

watch -n x <your command>


更改x

要获得使用watch命令及其选项的更多帮助,请运行man watch或访问此链接。

例如:以下将列出,每60秒钟,在同一终端上,查看Desktop目录的内容,以便您了解是否进行了任何更改:

watch -n 60 ls -l ~/Desktop


评论


+1,但使用扩展时要小心。例如,在调整终端大小时,请尝试watch -n 1'echo $ COLUMNS'和watch -n 1 echo $ COLUMNS之间的区别-前者每秒扩展一次,而后者仅在watch开始之前扩展一次。

–l0b0
2014年3月6日在16:06



我对此解决方案的问题是,您不能将watch作为进程运行,而只能使其在后台运行(例如,使用&disown)

– est
2015年5月13日下午2:06

有什么方法可以将手表与“启用历史记录”类型的命令一起使用?我喜欢使用手表,但有时我也希望看到以前执行的日志,而不仅仅是最后一个。是的,我知道我可以使用脚本(虽然为true)来完成此操作,但是使用watch实用程序要干净得多!

– rinogo
2015年9月14日在18:44



这对于较简单的命令有效,但是对于管道命令链接而言,这对我不起作用。.以下是我尝试过的命令=> cat api.log | grep“呼叫” | wc -l

– Sudip Bhandari
16-9-29在7:43



-bash:watch:找不到命令,macOS 10.14.1

–阿比吉特·萨卡(Abhijit Sarkar)
18-11-27在4:22



#2 楼

除了nux的答案外,您还可以在终端中使用此命令:

 while true; do <your_command>; sleep <interval_in_seconds>; done
 


示例

 while true; do ls; sleep 2; done
 


此命令将以2秒的间隔打印ls的输出。

使用Ctrl + C停止该过程。

watch的缺点很少


它不能使用任何别名命令。
如果任何命令的输出很长,滚动将无法正常工作。
设置最大时间间隔超过一定值有些麻烦。

watch将解释ANSI使用-c--color选项传递转义字符的颜色序列。例如,pygmentize的输出可以工作,但ls --color=auto的输出将失败。

在上述情况下,这可能是一个更好的选择。

评论


手表是存在的,我会说这没用

–布鲁诺·佩雷拉(Bruno Pereira)
2014年3月6日在16:36

我并不是说这个答案应该首先使用。手表在大多数情况下都很好。这就是为什么我一开始提到“除了nux的答案”。但是watch几乎没有问题,例如,不能在watch上使用任何别名命令。以ll为例,它是ls -laF的别名,但不能与watch一起使用。同样,如果任何命令的输出很长,则在使用watch滚动时会遇到麻烦。在这几种特殊情况下,此答案可能是一个更好的选择。

– souravc
2014年6月6日17:25

睡眠x更好-更容易杀死。

– d33tah
2014年8月8日15:43

这是一个不错的选择,与watch不同,它保留了命令历史记录。

– adelriosantiago
17年2月14日在18:31

watch的另一个怪异之处在于,如果我调整终端窗口的大小,它将再次运行命令。

–杰西·布坎南(Jesse Buchanan)
19-09-25在20:14

#3 楼

只是想了解souravc和nux的答案:


虽然watch可以在Ubuntu上完美运行,但是如果您希望“ Unix-fu”是纯净的,则可能要避免这种情况-例如,在FreeBSD上,watch是用于“监听另一条tty行”的命令。

while true; do command; sleep SECONDS; done也有一个警告-使用CTR + C可能更难以杀死您的命令。您可能希望使用while sleep SECONDS; do command; done-它不仅更短,而且更易于中断。需要注意的是它将首先休眠,然后运行命令,因此您需要等待一些SECONDS才能首次出现该命令。


评论


希望它可以作为答案而不是评论,可以接受-我想在这里展示另一种解决方案,而评论实际上会减少我的注意力。

– d33tah
2014年8月8日15:52

为什么在while循环中的何处睡眠并不重要?我找不到任何区别,无论如何,Ctrl + C都会立即中断循环。

–甜点
17年11月17日在8:03

@dessert:取决于您想从我想突破的东西。通常,ctrl + c只会杀死您的命令并进入睡眠状态,并且只有在您杀死true时才会中断。

– d33tah
17年12月11日在17:08

#4 楼

听起来像cron守护程序的理想任务,该守护程序允许运行定期命令。运行crontab -e命令以开始编辑用户的cron配置。其格式记录在crontab(5)中。基本上,您有五个与时间相关的,以空格分隔的字段,后跟一个命令:

The time and date fields are:

       field          allowed values
       -----          --------------
       minute         0-59
       hour           0-23
       day of month   1-31
       month          1-12 (or names, see below)
       day of week    0-7 (0 or 7 is Sunday, or use names)


例如,如果您想在每个星期二运行Python脚本,上午11点:

0 11 * * 1 python ~/yourscript.py


还有一些特殊的名称可以代替时间,例如@reboot。如果您需要创建一个临时目录,这将非常有帮助。来自我的crontab(列有crontab -l):

# Creates a temporary directory for ~/.distcc at boot
@reboot ln -sfn "$(mktemp -d "/tmp/distcc.XXXXXXXX")" "$HOME/.distcc"


评论


问题询问如何在终端中定期运行某些内容。 cron在幕后而不是在终端中运行

–北布拉德利
2014年12月15日19:22

#5 楼

如果要监视文件系统,则inotifywait非常出色,肯定会增加系统负载。

示例:

在第一个终端中键入以下命令:

$ inotifywait .


然后在第二个终端中,任何会影响当前目录的命令,

$ touch newfile


然后在原始终端inotifywait中将唤醒并报告事件

./ CREATE newfile2


或循环播放

$ while true ; do inotifywait . ; done
Setting up watches.  
Watches established.
./ OPEN newfile2
Setting up watches.  
Watches established.
./ OPEN newfile2
Setting up watches.  
Watches established.
./ DELETE newfile
Setting up watches.  
Watches established.
./ CREATE,ISDIR newdir
Setting up watches.  
Watches established.


评论


用户告诉你,没有脚本,也许他不想监视任何东西

–nux
2014年3月6日在16:36

我没有告诉他写脚本,我建议如果他们为了观察特定的文件系统事件而循环运行,那么inotifywait是有用的,并且比重复命令使用更少的资源。我经常在命令行上运行几个命令,例如grep某些InALogFile | less是脚本吗?

– X X Tian
2014年3月6日在16:43



它是一个很好的答案,尝试编辑它看起来更简单。

–nux
2014年3月6日下午16:45

还有比这更简单的方法。我不能遗漏命令。

– X X Tian
2014年3月6日在16:48

感谢@XTian,一个很棒的命令。现在,我还在手册页中看到您可以添加-m以连续监视而不循环。

– yoniLavi
2014年7月21日在16:06

#6 楼

您可以使用crontab。运行命令crontab -e并使用您首选的文本编辑器将其打开,然后添加此行
*/10 * * * *  /path-to-your-command

这将每10分钟运行一次命令
* */4 * * *  /path-to-your-command

这将每4分钟运行一次命令小时
另一种可能的解决方法
$ ..some command...; for i in $(seq X); do $cmd; sleep Y; done

X次重复。
Y次等待重复。
示例:
$ echo; for i in $(seq 5); do $cmd "This is echo number: $i"; sleep 1;done


评论


为什么这是一种改进?您只是通过将命令另存为变量来添加了一个多余的步骤。唯一要做的就是i)延长输入时间ii)强制您仅使用简单命令,不使用管道或重定向等。

– terdon
2014年7月3日,11:52

删除多余的变量

– Maythux
15年5月14日在11:24

#7 楼

您可以按照以下步骤创建自己的repeat命令;首先,打开您的.bash_aliases文件:

$ xdg-open ~/.bash-aliases


其次,将这些行粘贴到文件底部并保存:

repeat() {
n=
shift
while [ $(( n -= 1 )) -ge 0 ]
do
    "$@"
done
}


第三,关闭并再次打开终端,或键入:

$ source ~/.bash_aliases


等等!您现在可以像这样使用它:

$ repeat 5 echo Hello World !!!




$ repeat 5 ./myscript.sh


评论


xdg-open〜/ .bash-aliases行中有一个小的错字。它应该是:xdg-open〜/ .bash_aliases(即:下划线)

– ssinfod
18-2-4在1:21



#8 楼

上面提出的“监视”方法的另一个问题是它仅在处理完成时才显示结果。
“ date; sleep 58; date”仅在59秒后才显示2个日期。开始运行4分钟的内容后,它会缓慢显示多页内容,您将不会真正看到它。

另一方面,“ while”方法的问题在于它不需要考虑到任务持续时间。

while true; do script_that_take_between_10s_to_50s.sh; sleep 50; done


这样,脚本将每分钟运行一次,有时可能需要1分40秒。因此,即使cron能够每分钟运行一次,在这里也无法运行。

因此,要在shell生成时查看其输出并等待确切的请求时间,您需要看一下之前和之后的时间,并与while循环。

类似的东西:

while ( true ); do
  echo Date starting `date`
  before=`date +%s`
  sleep `echo $(( ( RANDOM % 30 )  + 1 ))`
  echo Before waiting `date`
  after=`date +%s`
  DELAY=`echo "60-($after-$before)" | bc`
  sleep $DELAY
  echo Done waiting `date`
done


这将输出以下内容:

您可以看到,该命令每分钟运行一次:

Date starting Mon Dec 14 15:49:34 EST 2015
Before waiting Mon Dec 14 15:49:52 EST 2015
Done waiting Mon Dec 14 15:50:34 EST 2015

Date starting Mon Dec 14 15:50:34 EST 2015
Before waiting Mon Dec 14 15:50:39 EST 2015
Done waiting Mon Dec 14 15:51:34 EST 2015


因此,只需将“ sleep echo $(( ( RANDOM % 30 ) + 1 ))”命令替换为您想要的内容将在终端/外壳上每分钟运行一次。如果您想要另一个时间表,只需根据需要更改“ 60”秒。

没有调试行的更短版本:

while ( true ); do
  before=`date +%s`
  sleep `echo $(( ( RANDOM % 30 )  + 1 ))` # Place you command here
  after=`date +%s`
  DELAY=`echo "60-($after-$before)" | bc`
  sleep $DELAY
done


评论


回复我自己...如果您的命令花费的时间超过了您配置的延迟,则$ DELAY将获得负值,并且sleep命令将失败,因此脚本将立即重新启动。需要意识到这一点。

– jmspaggi
15年12月14日在21:06

#9 楼

while true; do <your command>; sleep <time interval>;done

在这一行代码中,1.该过程将随着我们使用while循环而连续运行,
2。然后执行命令,
3。睡眠一段时间
作为示例while true; do ./git.bash;sleep 20;done
每20秒此行自动将我的代码推送到GitHub