热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linuxshell脚本,Linux下的西红柿时间管理法III

Linuxshell脚本,Linux下的西红柿时间管理法III8.需要的支持技术我们说到希望从atq指令的输出中,自动计算出还剩多长时间休息,而不是靠用户自己计算。at
Linux shell脚本,Linux下的西红柿时间管理法 III

8. 需要的支持技术

我们说到希望从atq指令的输出中,自动计算出还剩多长时间休息,而不是靠用户自己计算。atq的输出是这样的:

1 3444 Tue Nov 27 18:47:00 2012 r young
2 3445 Tue Nov 27 18:48:00 2012 r young

第1行是提醒的任务,第2行是锁屏的任务。这里已经包含了执行任务的时间,即Tue Nov 27 18:47:00 2012,我们要做的是把这段数据抽出来,跟当前时间做减法。

单纯这么一说,似乎任务很简单,但事实要更复杂一些,一会儿你会看到。在看到任务的时候就确定有哪些支持技术,是非常困难的。难到就像,你还没有迈出第一步,就确定以后的路上会遇到哪些大河要跨过,哪些高山要翻越。不知道以后会有什么困难就无从准备,而那些没有做好准备就遇到的困难,正是扼杀成功的原因。怎么办呢?无他,或者,如果我们有经验,走过一次,那就已经知道了;又或者,有个向导带着我们走,他已经走过一次;又或者,干脆现在走一次,然后就知道了。

在没走之前先猜测一下会怎么样,在走的每一步记录,这正是工程师的基本素养:估算和度量。

9. 探索的过程

我们准备写一个shell脚本,运行的时候显示出当前时刻距离atq中的第二行任务还剩多长时间

9.1 解析数据

要从

1 3444 Tue Nov 27 18:47:00 2012 r young
2 3445 Tue Nov 27 18:48:00 2012 r young

中把"Tue Nov 27 18:48:00 2012"单独取出来,是按约定的语法或格式处理字符串,在编译原理里叫作做解析。解析简单的数据的手段很多,比如sed,比如cut。

我这样实现的:
atq -q r | cut -f2 | cut -d' ' -f 1,2,3,4,5 | sort | sed -n 2p

这是由一组管理连起来的进程组成。"|"就是管道,表示前一个进程的输出作为后一个进程的输入。我们一步一步看。这些进程,包括cut,sort,sed,都是字符串处理常用工具,具体的用法和参数我也记不住,常要看手册或者google。

第一步,atq -q r,表示只列出队列r中的任务。执行效果是:

~ $ atq -q r
3502 Thu Nov 29 19:33:00 2012 r young
3503 Thu Nov 29 19:34:00 2012 r young

第二步,cut -f2,表示取出第二个字段。效果相当于下面这两行:

~ $ atq -q r | cut -f2
Thu Nov 29 19:33:00 2012 r young
Thu Nov 29 19:34:00 2012 r young

只去除了3501和3502两个序号。不要小巧这点工作,这是一个很好的开始,并且表明我们能够操作字符串了。

第三步,cut -d' ' -f 1,2,3,4,5,表示取第1、2、3、4、5字段,并且以空格作为分隔符划分字段,效果如下,切掉了后面的队列名和用户名,离目标更近了:

~ $ atq -q r | cut -f2 | cut -d' ' -f 1,2,3,4,5
Thu Nov 29 19:33:00 2012
Thu Nov 29 19:34:00 2012

第四步,sort,排序,默认是由小到大,效果如下:

~ $ atq -q r | cut -f2 | cut -d' ' -f 1,2,3,4,5 | sort
Thu Nov 29 19:33:00 2012
Thu Nov 29 19:34:00 2012

这是为了下一步有确定的输入,以便挑出正确那行。

第五步,sed -n 2p,选择输出第二行,效果如下:

~ $ atq -q r | cut -f2 | cut -d' ' -f 1,2,3,4,5 | sort | sed -n 2p
Thu Nov 29 19:34:00 2012

小结,我们由atq输出的任务

3502 Thu Nov 29 19:33:00 2012 r young
3503 Thu Nov 29 19:34:00 2012 r young

得到了将会锁屏的时间:

Thu Nov 29 19:34:00 2012

这一时间,将用于下一步的做差计算。慢着,任务的时间和当前时间做差,当前时间是什么?

当前时间可以用date获得,效果如下:

~ $ date
Thu Nov 29 19:18:20 2012

9.2 计算时间差

求时间点 Thu Nov 29 19:18:20 2012 和时间点 Thu Nov 29 19:34:00 2012 的差,当然不能把它们直接相减了事。有的同学可能想到了,可以按上面的方法解析出日期、小时、分钟、秒,然后再做减法。这也能解决,不过由于时间相减是个工程中可以想见的常用的功能,所以,应该有现成的解决方案。这也是个原则,凡是常用的功能,一定有常用的方案或者函数。至于什么是"常用的"功能,你常做小项目,就会知道。

去做,就会明白。就像,怎么成为好人,你希望别人如何对你,别人如何做你会感动,按照那个要求去做,那就是好人了,至少会被别人评价为"好人"。

时间相减这个功能的常用方案,我这样实现:

1 task=$(date -d "$task" +%s)
2 now=$(date -d "$(date)" +%s)
3 diff=$(($task-$now))

第一行中,执行了一个指令"date -d <什么东西> +%s",这代表把<什么东西>里的时间转化为自1970年1月1日起到<什么东西>这个时间,相差了多少秒。为什么是1970年1月1日而不是1949年呢,因为大家可能还记得C语言和UNIX操作系统诞生于1969-1970年。那个<什么东西>就是"Thu Nov 29 19:18:20 2012"这样的东西。

执行效果是这样的:

~$ date -d "Thu Nov 29 19:18:20 2012" +%s
1354187900

到底多少秒,我们也并不需要关心,一会儿能用来求差就行了。

"task=$(date -d "$task" +%s)"中代替了<什么东西>的,不是固定的时间,像"Thu Nov 29 19:18:20 2012",而是"$task",它表示一个变量,名字叫做task。这个task是这么来的:

task=$(atq -q r | cut -f2 | cut -d' ' -f 1,2,3,4,5 | sort | sed -n 2p
)

这就像在上面三行代码里,也有个变量赋值给task:

task=$(date -d "$task" +%s)

在等号右边的task的值是"Thu Nov 29 19:18:20 2012",在等号左边的task的值是上面的那个秒数 1354187900。

第2行为now赋值为"此刻"date的秒数。
2 now=$(date -d "$(date)" +%s)

第3行求差得到diff,锁屏时刻的秒数 (距1970年元旦 )和此刻的秒数 (距1970
年元量) 的差:

3 diff=$(($task-$now))

这样,我们就得到了,还有多少秒到锁屏时间,虽不够友好,但是离目标又近了一步。

9.3 格式调整

我不希望这样的结果,还剩778秒到休息锁屏时间,虽然这和12分钟58秒没什么本质区别。我希望它这样提示 12:58。

9.3.1 换算

这个好办,对60做除法,商就是分钟数,余数就是秒数。既然这么显然,那shell一定提供了这样的支持技术,果然一goolge就有。其实上面这些,有不少我忘记了或者记不清的,我也都去google了。关键在于,你得知道那东西存在,才能google。

这里[http://www.computing.net/answers/unix/remainder-operator/6820.html]有一段

: Use the % operator. Check below
: --
: 1. expr 5 / 2 gives 2 as Quotient.
: 2. expr 5 % 2 gives 1 as Remainder.

所以,我这样实现:

minute=$((diff/60))
sec=$((diff%60)) 

又是变量赋值。

9.3.2 条件判断

但是,还有些别的可能,比如只剩下12分5秒的时候,我不希望显示成

还剩12:5

而是希望得到:

还剩12:05

这需要条件判断。查到shell中的条件判断的语法:

if [cond]; then
fi

当然,前提还是,你得确信知道条件判断这种东西是存在的。

我这样实现:

1 if [ "$sec" -lt "10" ]; then
2     sec=0$sec
3 else
4     sec=$sec
5 fi

9.3.3 连接字符串

上面的代码中,第2行中的"0$sec",把常量字符串与变量相连接,就是直接接起来写,这个我也试了一下,如下:

$ a='hello'
$ b='world'
$ c=$a$b
$ echo $c
helloworld

9.3.4 判断空行

还有另一个可能。如果还有不到一分钟就休息了,atq的输出将只有一行,因为提醒音的那个任务已经执行完了。

我们需要判断输出有几行,或者说,我们需要判断空行。goolge得到:

[http://stackoverflow.com/questions/3061036/how-to-find-variable-is-empty-or-in-shell-script]

: In bash at least: if [[ -z "$var" ]]

: the command line "man test" is your friend.

最后一行对应的UNIX谚语是:男人是最好的,原文 "man is the best"。这里的man,不是男人,而是manual的缩写,unix下的一个指令 man,用来查手册的。尽管大家都心知肚名man不是男人的意思,还是有不少unix/linux发行版中的man指令有个等同的指令,名字叫做woman。恩,而且woman和man不仅平等,而且完全一样。

我这样判断空行:

1 if [ -z "$task" ]; then
2     echo "No more than 1 minute left to have a break."
3     exit 0
4 fi

10 bug修正和功能增加

人生总是只有开始,才知道原来后面有这么多苦难;程序总是开跑才发现,原来总有bug存在。王子和公主从此以后过上无忧无虑的幸福生活,这种事只有在童话里才有。

没啥,逢山开路,遇水搭桥,碰到bug就杀掉。

10.1 排序

atq输出的时候,输出我也不知道是怎么个顺序,所以有了上面的sort指令。最初的版本中是没有的。

10.2 只加入指定的队列

虽然还没有出现这样的情况,但是在其他的时候,或者其他的程序,可能也要使用at任务的队列。所以,我改成只选其中一个队列使用。

atq -q r,只显示队列r中的任务。

at ... -q r,向队列r中添加任务。

11. 秘密

表面上看,上面是演示如何实现西红柿时间管理。没错,西红柿时间管理确实很有效,我常用。但是,正如钢琴老师教你弹的那些小曲子也确实挺好听的,但是她教你弹曲子的目的绝对不仅是欣赏这些曲子本身,而是更注重练习曲目时所得到的能力提升。这个小项目也是一样。

以上这些步骤看起来很流畅,先这样,再那样,然后又如何,最后问题解决了。等到你实践的时候可能略有不同。这种差异的来源是因为:我其实不是盲目地探索的,因为学习过其他的语言、做过其他的小项目,所以能够猜到应该有这样的那样的解决方案存在,所以我是有意去寻找每一步的技术和有计划地逼近终点的。换句话说,我经常地猜到了那里应该有这样的技术存在,然后才去google。而google并不能告诉你你不知道的东西。


如同《怎样解题:数学思维的新方法》[http://book.douban.com/subject/2124114/]这本书所说的,教师解题的过程,并不是盲目的,而是假设或计划将会如何,然后朝着那个方向推理和努力。我们作为学生需要体会的,是在观摩教师解题过程中的那些节点和方向。然后可能还要思考,他是怎么知道到这里就会有这个技术了呢?就像故事里讲的,孩子问雕塑师,你先前怎么知道石头里有个女人的呢。


长春的河已经开始封冻,大雪还在继续。更多照片,请移步[http://www.douban.com/photos/album/82021426/]。



--------------------


博客会手工同步到以下地址:


[http://giftdotyoung.blogspot.com]


[http://blog.csdn.net/younggift]

推荐阅读
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 使用C++编写程序实现增加或删除桌面的右键列表项
    本文介绍了使用C++编写程序实现增加或删除桌面的右键列表项的方法。首先通过操作注册表来实现增加或删除右键列表项的目的,然后使用管理注册表的函数来编写程序。文章详细介绍了使用的五种函数:RegCreateKey、RegSetValueEx、RegOpenKeyEx、RegDeleteKey和RegCloseKey,并给出了增加一项的函数写法。通过本文的方法,可以方便地自定义桌面的右键列表项。 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 使用圣杯布局模式实现网站首页的内容布局
    本文介绍了使用圣杯布局模式实现网站首页的内容布局的方法,包括HTML部分代码和实例。同时还提供了公司新闻、最新产品、关于我们、联系我们等页面的布局示例。商品展示区包括了车里子和农家生态土鸡蛋等产品的价格信息。 ... [详细]
  • REVERT权限切换的操作步骤和注意事项
    本文介绍了在SQL Server中进行REVERT权限切换的操作步骤和注意事项。首先登录到SQL Server,其中包括一个具有很小权限的普通用户和一个系统管理员角色中的成员。然后通过添加Windows登录到SQL Server,并将其添加到AdventureWorks数据库中的用户列表中。最后通过REVERT命令切换权限。在操作过程中需要注意的是,确保登录名和数据库名的正确性,并遵循安全措施,以防止权限泄露和数据损坏。 ... [详细]
  • 本文整理了Java中java.lang.NoSuchMethodError.getMessage()方法的一些代码示例,展示了NoSuchMethodErr ... [详细]
  • 本文介绍了使用readlink命令获取文件的完整路径的简单方法,并提供了一个示例命令来打印文件的完整路径。共有28种解决方案可供选择。 ... [详细]
  • Python脚本编写创建输出数据库并添加模型和场数据的方法
    本文介绍了使用Python脚本编写创建输出数据库并添加模型数据和场数据的方法。首先导入相应模块,然后创建输出数据库并添加材料属性、截面、部件实例、分析步和帧、节点和单元等对象。接着向输出数据库中添加场数据和历程数据,本例中只添加了节点位移。最后保存数据库文件并关闭文件。文章还提供了部分代码和Abaqus操作步骤。另外,作者还建立了关于Abaqus的学习交流群,欢迎加入并提问。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 本文介绍了Java调用Windows下某些程序的方法,包括调用可执行程序和批处理命令。针对Java不支持直接调用批处理文件的问题,提供了一种将批处理文件转换为可执行文件的解决方案。介绍了使用Quick Batch File Compiler将批处理脚本编译为EXE文件,并通过Java调用可执行文件的方法。详细介绍了编译和反编译的步骤,以及调用方法的示例代码。 ... [详细]
  • 本文整理了Java中org.apache.hadoop.hbase.client.Increment.getDurability()方法的一些代码示例,展示了 ... [详细]
author-avatar
此女我很爱_484
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有