免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 4726 | 回复: 23

[数值计算] 请教计算程序执行时间的shell脚本 [复制链接]

论坛徽章:
0
发表于 2018-10-19 20:51 |显示全部楼层
本帖最后由 yexingqi 于 2018-10-19 20:56 编辑

先祝大家周未愉快!!

我当前在写一个小脚本,花了一天多了仍然不完美。 所以向大家请教一下,我的目的是:
1. 循环计算某个程序的执行时间, 如果超过指定的时间后就报警。 并记录它实际执行了多长时间。(如果超过2分钟仍然没有执行完毕那就放弃时间记录,只提示超过2分钟)
2. 考虑到这个程序在执行时可能会卡死长时间无响应。即超出指定的时间,这时就需要脚本报警。

我按这个思路写了以下脚本,勉强能实现一部分的功能,想请各位大侠能不能帮忙给些建议改善一下呢? 先谢谢了!



#!/bin/bash
endfile=/tmp/1111.txt
endfile2=/tmp/2222.txt
rm -rf $endfile

my_toolstatus(){
du -sh /data    ## 这里的数据会动态改变,所以造成这个命令的总共执行时间不固定,有时几秒有时需要1分钟

if [ -f $endfile2 ] ; then
rm -rf $endfile
rm -rf $endfile2
echo "will exit"
exit 0
else
echo "going to create endfile"
date +'%Y-%m-%d %H:%M:%S' >$endfile
fi
}

while :
do
export endtime=""
rm -rf $endfile
starttime=`date +'%Y-%m-%d %H:%M:%S'`

my_toolstatus &    #这里加上 & 符号就是为了让funation里的程序在执行时卡死也不影响主shell脚本运行和统计

sleep 3     ## 这里设置超过3秒就报警
if [ ! -f $endfile ] ; then
touch $endfile2
fi

endtime=`cat $endfile 2>/dev/null`

if [ "$endtime" ] ; then
start_seconds=$(date --date="$starttime" +%s)
end_seconds=$(date --date="$endtime" +%s)
echo "using the time is: "$((end_seconds-start_seconds))"s"
nnumber=$((end_seconds-start_seconds))
else
echo "process problem !!"
fi
done

论坛徽章:
0
发表于 2018-10-19 20:55 |显示全部楼层
万分感谢,如果能得到大家的指点!!!!

论坛徽章:
0
发表于 2018-10-20 16:37 |显示全部楼层
1 我给你写了个powershell脚本例子,因为我只会powershell,你按照改写成shell的即可。

  1. $开始时间 = Get-Date
  2. $结束时间 = $开始时间.AddMinutes(2)

  3. start-job -name aaa -ScriptBlock {
  4.         #你的任务
  5.         #随时调整这个值。
  6.         start-sleep -Seconds 30
  7. }

  8. while ((get-date) -lt $结束时间)
  9. {
  10.         start-sleep -Seconds 3
  11.         if ((get-job -name aaa).state -eq 'Running')
  12.         {
  13.                 $超时时间 = (get-date) - $开始时间
  14.                 Write-Warning "报警: 任务已经运行时间超过 $超时时间 "
  15.         }
  16.         else
  17.         {
  18.                 $总时间 = (get-date) - $开始时间
  19.                 Write-Warning "任务正常结束。耗时总计:$总时间  "
  20.                 exit 0
  21.         }
  22. }
  23. Write-Warning '任务运行超过2分钟,任务将被强制结束'
  24. Stop-Job -Name aaa
  25. remove-job -name aaa -Force
复制代码



2 此脚本win,linux通用。win我调试通过。

3 shell好,shell妙,就得学shell,bash。

论坛徽章:
0
发表于 2018-10-20 16:56 |显示全部楼层
13行改成了7


PS A:\pscode> a:\pscode\TEMP_2018\temp182\aaa.ps1

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
25     aaa             BackgroundJob   Running       True            localhost            ...

警告: 报警: 任务已经运行时间超过 00:00:07.0624822
警告: 报警: 任务已经运行时间超过 00:00:14.0636903
警告: 报警: 任务已经运行时间超过 00:00:21.0642892
警告: 报警: 任务已经运行时间超过 00:00:28.0643016
警告: 任务正常结束。耗时总计:00:00:35.0799206

论坛徽章:
0
发表于 2018-10-20 18:54 |显示全部楼层
本帖最后由 yexingqi 于 2018-10-20 19:14 编辑
本友会机友会摄友会 发表于 2018-10-20 16:37
1 我给你写了个powershell脚本例子,因为我只会powershell,你按照改写成shell的即可。

大神好利害! 我试过在win下面是成功的!! 赞赞赞! 谢谢您的帮助!
另外,稍跟我的要求有点不同,我希望这个脚本是一直在后台循环执行,因为某个程序的执行时间时长时短, 以您的脚本为例,我想要的结果是:只要aaa任务它在3秒钟之内能执行完,那么这个脚本就会继续循环检查。 直到发现那个程序的执行时间超过了3秒,这时就开始记录出错的时间了,最后超过30秒后再将该aaa的任务停止或删除。

而您的脚本是: aaa的任务执行时间没有超过3秒则直接将检查的工作停止了。


我的应用主要是在linux 下面。 我同时也在按您的思路尝试用bash shell来实现这个要求,二者都会的话就最好了。 碰到一点困难还没有成功,部分的功能像$结束时间 = $开始时间.AddMinutes(2)在shell下面没办法加,只能想别的办法代替。 我继续再多试一下。。。


论坛徽章:
4
15-16赛季CBA联赛之青岛
日期:2018-07-09 14:17:2815-16赛季CBA联赛之八一
日期:2018-08-06 15:30:0515-16赛季CBA联赛之广东
日期:2018-08-09 09:11:2115-16赛季CBA联赛之佛山
日期:2019-02-14 09:26:31
发表于 2018-10-20 20:53 |显示全部楼层
  1. #!/bin/bash
  2. stime=$(date +%s);
  3. time_limit=3;
  4. x=0;

  5. echo "start time: $stime";

  6. while :;do
  7.   let x+=1;
  8.   etime=$(date +%s);
  9.   if [ "$etime" -eq "$(($stime+$time_limit))" ];then
  10.     echo "end time: $(date +%s)";
  11.     echo "out of time";
  12.     exit 2;
  13.   fi
  14. done
复制代码

时间戳计算时间,时间戳也方便转换格式,条件判断,然后 break loop 或者 exit 按需

论坛徽章:
0
发表于 2018-10-20 21:36 |显示全部楼层
christmas1102 发表于 2018-10-20 20:53
时间戳计算时间,时间戳也方便转换格式,条件判断,然后 break loop 或者 exit 按需

抱歉,请教一下您这个脚本在哪里放运行程序的命令呢?  我是希望它循环检查执行的程序的运行时间:例如du -sh /xxx ,如果不超过某个时间就隔几秒反复检查,如果超过某个时间就警报出来。
我这里运行的结果是这样:
start time: 1540042269
end time: 1540042272
out of time
似乎不太合乎我的需求。

谢谢!!


论坛徽章:
4
15-16赛季CBA联赛之青岛
日期:2018-07-09 14:17:2815-16赛季CBA联赛之八一
日期:2018-08-06 15:30:0515-16赛季CBA联赛之广东
日期:2018-08-09 09:11:2115-16赛季CBA联赛之佛山
日期:2019-02-14 09:26:31
发表于 2018-10-22 10:25 |显示全部楼层
回复 7# yexingqi

你误会了,这个不是解决方案,只是多个思路的范例脚本开始指定一个开始的时间戳,脚本结束赋予一个结束时间戳,通过格式转换,可以得出最终脚本的执行时间,最简单是使用 time命令

另外,循环体内开始段可以设定时间戳,限制时间,判断语句,单次循环结束清空时间戳,下次循环重新计时。干净点的话,可以分别对循环体以及计时器进行封装,这样写能符合你的要求,但是会影响脚本执行效率~

论坛徽章:
0
发表于 2018-10-22 11:39 |显示全部楼层
回复 8# christmas1102

谢谢您了. 周未也一直在参考您的这些代码. 虽然我现在还没有成功,但还学习了很多. 感谢您的共享!

论坛徽章:
0
发表于 2018-10-22 13:54 |显示全部楼层
本帖最后由 本友会机友会摄友会 于 2018-10-22 16:21 编辑

1第二版的脚本是这样。

  1. $开始时间 = Get-Date
  2. $报警时间 = $开始时间 + [timespan]::FromSeconds(20)
  3. $结束时间 = $开始时间.AddMinutes(2)

  4. start-job -name aaa -ScriptBlock {
  5.         #你的任务
  6.         #随时调整这个值。
  7.         start-sleep -Seconds 30
  8. }

  9. while ((get-date) -lt $结束时间)
  10. {
  11.         start-sleep -Seconds 7
  12.         Write-host -ForegroundColor Green '常规检测间隔'
  13.         if ((get-job -name aaa).state -eq 'Running')
  14.         {
  15.                 if ((get-date) -ge $报警时间)
  16.                 {
  17.                         $运行时间 = (get-date) - $开始时间
  18.                         Write-host  -ForegroundColor Yellow "报警: 任务已经运行时间超过 $运行时间 "
  19.                 }
  20.         }
  21. }
  22. Stop-Job -Name aaa
  23. remove-job -name aaa -Force
  24. Write-Warning '任务运行超过2分钟,任务将被强制结束'
  25. exit 1
复制代码


2这个脚本细化了少许。把检测周期,和报警周期分开了。去掉了任务结束就退出。

3 输出:
PS A:\pscode> a:\pscode\TEMP_2018\temp182\aaa2.ps1

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
1      aaa             BackgroundJob   Running       True            localhost            ...
常规检测间隔
常规检测间隔

常规检测间隔
报警: 任务已经运行时间超过 00:00:21.2431567

常规检测间隔
报警: 任务已经运行时间超过 00:00:28.2583446

常规检测间隔  《------------5*7=35秒时,任务已经结束。
常规检测间隔
常规检测间隔
常规检测间隔
常规检测间隔
常规检测间隔
常规检测间隔
常规检测间隔
常规检测间隔
常规检测间隔
常规检测间隔
常规检测间隔
常规检测间隔
常规检测间隔
警告: 任务运行超过2分钟,任务将被强制结束

4 执行完,那么这个脚本就会继续循环检查。---你在顶楼没说这个。你在5楼增加了这个需求。

5 我也按照需求更改了脚本。但是捏,并没有用。根据脚本的输出可知,任务30秒就结束了。
30秒后,任务结束了,你还 裤衩衩检查,有啥用呢?顶楼你说不结束怎样,没说任务结束怎样。我就按照我的思路来了。

6结论:这些代码我去掉了,但去掉的不应该。我的思路是对的。任务结束后,就不检测了。若想检测,就重新run脚本,重run任务。
  1.         else
  2.         {
  3.                 $总时间 = (get-date) - $开始时间
  4.                 Write-Warning "任务正常结束。耗时总计:$总时间  "
  5.                 exit 0
  6.         }
复制代码


7 linux上若能安装上ps,也可以跑。shell没法计算时间。没有内置的。或者说计算时间麻烦。

centos7及以上,安装powershell:
curl -o /etc/yum.repos.d/microsoft.repo  https://packages.microsoft.com/config/rhel/7/prod.repo
sudo yum remove -y powershell #删除旧版
sudo yum install -y powershell
pwsh -c 'mkdir -p  "$env:HOME/.config/powershell" '
pwsh -c 'Add-Content  -Value 'Set-PSReadlineOption -EditMode Windows' -LiteralPath $profile '


ubuntu1604:
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
sudo curl -o /etc/apt/sources.list.d/microsoft.list https://packages.microsoft.com/config/ubuntu/16.04/prod.list
sudo apt-get update
sudo apt-get remove -y powershell #删除旧版
sudo apt-get install -y powershell
pwsh -c 'mkdir   -p "$env:HOME/.config/powershell" '
pwsh -c 'Add-Content  -Value 'Set-PSReadlineOption -EditMode Windows' -LiteralPath $profile '
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP