编写你的shell其实很简单

引语:我本人以前并没有写过shell脚本,也许是因为懒,也许是没有被逼到要去写shell的地步。但是,前段时间,工作需求,要求重新跑几个月的脚本,这些脚本是每天定时进行跑的,而且每天是好几个脚本一起关联跑的。你也许会说,这太简单了,写个循环,然后,让他自己去跑就行了。是的,你可以很顺手的用你的编程语言去写循环,如PHP。但是,你知道,这样做其实是改变了代码结构了,鬼知道会导致什么结果呢? 并且,我并不保证里面所有代码的意思,我都懂!那么,问题来了,在不改变原代码的前提下,怎样去循环这几个月的时间呢? 没错,那就是,模拟真实运行时的情况,传入需要接收的日期参数(前提是你的代码里面已经有了这个门)!你知道,这种定时脚本都有一个优雅的名字,crontab,那么,就是shell了,你要做的就是写shell了。

  没有写过shell? 没关系了,其实需求确定之后,你显然已经知道,这太简单了。不就是语法问题吗? 你别告诉我你不会谷歌,不会百度!

  我就先抛几个需要考虑的点,后面直接给代码吧!

    1、怎样获取当前时间,并转换成你需要的格式? 关键词: date

    2、怎样防止同时多次运行同一个内容? 关键词: lock

    3、怎样让程序运行完一次之后,冷却执行? 关键词: sleep

    4、怎样指定运行时间段,counter或者起始日期? 关键词: while, let, expr

    5、附加:怎样知道当前的运行状态如何了? 关键词: echo ,  progress

把这些问题考虑好了,你就一步步去写吧,不知道语法的,直接谷歌、百度,代码参考如下:

#/bin/bash
# @author: youge
# @date: 2015-12-22

startDate="2015-11-24"    # when to start
startDateTimestamp=`date -d "$startDate" +%s`
endDate="2015-12-14"      # when to end
endDateTimestamp=`date -d "$endDate" +%s`
sleepTime=25        # to take a break
haveSthUndo=0      # check if there is something undo , if not , exit the program

rootDir='/cygdrive/d/wamp/ppi/'
dir=$rootDir"cron/"

itemArr=("itemA" "itemB" "itemC")  # the items you want to run there
for item in ${itemArr[@]}
do
  runFile=$rootDir$item".run";
  if [ ! -f "$runFile" ] ; then
  haveSthUndo=1;
  echo $item" runs on me" $runFile " touched";
  echo -e "script startTime: "`date "+%Y-%m-%d %H:%M:%S"` "\nbeginDate:" $startDate "\nendDate:" $endDate "\npath:" $dir >> $runFile
  touch "$runFile";
  break;
  else
  echo $item "is runing, skipped. " $runFile;
  fi
done;
if [ $haveSthUndo -ne 1 ]; then
  echo -e "Nothing to do now ...\ncheck it...";
  exit;
fi
echo "haveSthUndo eq: " $haveSthUndo;

while [[ $endDateTimestamp -ge $startDateTimestamp ]]
do
  runDate=`date -d @$startDateTimestamp +%Y-%m-%d`;    #1987-01-06
  params="item=$item&d=$runDate";
  msg="[`date "+%Y-%m-%d %H:%M:%S"`] now we run the date: "${runDate}" [params]: "${params};
  echo $msg;          # to show me ...
  echo $msg >> $runFile;

  # run the scripts below
  cd $dir &&
    /bin/php ./script1.php $params &&
    /bin/php ./script2.php $params &&
    /bin/php ./scriptx.php $params
  # run the scripts upon

  startDateTimestamp=`expr $startDateTimestamp + 86400`;    # run the next day ...

  echo " ___sleeping for $sleepTime seconds ... ";
  x='';
  for ((itime=0; itime<$sleepTime; itime++)); do
    let itime2=$itime+1;
    progress=`expr $itime2 \* 100 / $sleepTime`;
    printf "cooling:[%-"$sleepTime"s]%d%%\r" $x $progress
    x=#$x
    sleep 1;              # sleep xx seconds to run the next time, show the progress
  done;
  echo;
done;
echo "[`date "+%Y-%m-%d %H:%M:%S"`] the end." >> $runFile;

#end of the file

附录:

根据本人初涉shell,遇到的问题例举如下,希望可以减少大家走弯路的时间:

  1、整个shell脚本,其实就相当于你在终端输入的一系列命令,如果想在shell里做什么,就先想想在终端可以做什么吧,字符的的连接,就是直接用 "" 双引号,输出,变量定义无 $ 符号,但是使用时一定要加上 $ 符号。

  2、"="  赋值符号,两边一定不能有空格,这和其他语言有区别,尤其是你还有自己代码美观风格时特别注意,否则会报语法错误!

  3、for 中的数组内容是以 " " 空格分隔,而非 "," 逗号分格

  4、条件判断 [ true ] 中括号 后面需要有一个空格,但是两个中括号之间不能有空格如 [[ true ]]

  5、while 条件判断可以用 () 括号,也可以用 [[ ]] 中括号

  6、如果用windows写shell,一定要注意换行符格式 \n 而非 \r\n , 需要借助一些编辑器(如notepad++)更改换行符格式!

终了: 其实,语言只是一种工具,永远不会太难(太难也不会有人用啊),真正能让工具工作起来的,是你的思想!

其实很简单,Just do it .

[ root @my-pc ]$ sh urScripts.sh    #see you next time

以上就是本文的详细内容,希望对大家的学习有所帮助。

(0)

相关推荐

  • 大小写字母转换的shell脚本代码

    以下脚本,可以进行目录或文件大小写字母转换,代码如下: 复制代码 代码如下: #!/bin/sh #edit by www.jb51.net # [:upper:] [ A - Z ] # [:lower:] [ a - z ] # [:digit:] [ 0 - 9 ] # [:alnum:] [ 0 - 9 a - z A-Z] # [:space:] 空格或t a b键 # [:alpha:] [ a - z A - Z ] # tr for f in * do echo $f | tr

  • shell脚本连接、读写、操作mysql数据库实例

    本文介绍了如何在shell中读写mysql数据库.主要介绍了如何在shell 中连接mysql数据库,如何在shell中创建数据库,创建表,插入csv文件,读取mysql数据库,导出mysql数据库为xml或html文件, 并分析了核心语句.本文介绍的方法适用于PostgreSQL ,相对mysql而言,shell 中读写PostgreSQL会更简单些. 1. 连接mysql 数据库 shell中连接数据库的方法很简单,只需要指定用户名,密码,连接的数据库名称,然后通过重定向,输入mysql的语

  • 用PHP和Shell写Hadoop的MapReduce程序

    使得任何支持标准IO (stdin, stdout)的可执行程序都能成为hadoop的mapper或者 reducer.例如: 复制代码 代码如下: hadoop jar hadoop-streaming.jar -input SOME_INPUT_DIR_OR_FILE -output SOME_OUTPUT_DIR -mapper /bin/cat -reducer /usr/bin/wc 在这个例子里,就使用了Unix/Linux自带的cat和wc工具来作为mapper / reducer

  • Shell脚本注释写法

    一.单选注释 以"#"开头的行就是注释,会被解释器忽略. 复制代码 代码如下: #-------------------------------------------- # 这是一个自动打ipa的脚本,基于webfrogs的ipa-build书写: # https://github.com/webfrogs/xcode_shell/blob/master/ipa-build # 功能:自动为etao ios app打包,产出物为14个渠道的ipa包 # 特色:全自动打包,不需要输入任

  • shell结合expect写的批量scp脚本工具

    在部署一个任务时,其中有一项必须的过程就是将一些文件,如安装包发送到大量的服务器上去.虽然已有宇哥的脚本可用:通过paramiko模块提供的ssh和scp功能编写的python脚本.但我到现在还在对python的恐惧之中(虽然已经在空闲时间努力去学习了),所以使用了shell和expect脚本结合的方式,写了这个批量scp的脚本工具. expect用于自动化地执行linux环境下的命令行交互任务,例如scp.ssh之类需要用户手动输入密码然后确认的任务.有了这个工具,定义在scp过程中可能遇到的

  • PowerShell入门教程之编写和使用脚本模块实例

    现在通过编写模块就可以在PowerShell命令行或者脚本中管理大型.分布式软件系统,就像Exchange Server和SharePoint Server正在做的那样.你有这样的需求吗? 模块.脚本模块 模块是PowerShell V2中引入的概念,用以改进之前提出的"管理单元".将管理单元也作为模块(二进制模块)处理之后,PowerShell中就包括两种模块--脚本模块和二进制模块.那么什么是模块呢?模块就是包含一些PowerShell命令.项的程序包,它以一个整体被分发共享和加载

  • Shell脚本一次读取文件中一行的2种写法

    写法一: 复制代码 代码如下: #!/bin/bash while read line do       echo $line     #这里可根据实际用途变化 done < urfile 写法二: 复制代码 代码如下: #!/bin/bash cat urfile | while read line do     echo $line done 注意:以上代码中urfile 为被读取的文件 Shell读取文本文件 方法一:通过命令获取所需内容,传递给变量 复制代码 代码如下: var1=$(g

  • windows下写的shell脚本在linux执行出错的解决办法

    在Windows下写了一个shell脚本,上传到Linux下执行时报错: 复制代码 代码如下: [root@localhost test]# ./test.sh   -bash: ./test.sh: /bin/sh^M: bad interpreter: No such file or directory test.sh源码:  复制代码 代码如下: #!/bin/sh echo "test shell " 由于自己对shell不太熟悉,找同事沟通了后了解了原委,主要原因是test.

  • shell脚本编写的俄罗斯方块游戏代码

    粘贴以下代码到一个空的Shell脚本文件中,并在Bash 中运行即可! 复制代码 代码如下: #!/bin/bash # Tetris Game# 10.21.2003 xhchen<[email]xhchen@winbond.com.tw[/email]> #APP declarationAPP_NAME="${0##*[\\/]}"APP_VERSION="1.0" #颜色定义cRed=1cGreen=2cYellow=3cBlue=4cFuchsi

  • 编写你的shell其实很简单

    引语:我本人以前并没有写过shell脚本,也许是因为懒,也许是没有被逼到要去写shell的地步.但是,前段时间,工作需求,要求重新跑几个月的脚本,这些脚本是每天定时进行跑的,而且每天是好几个脚本一起关联跑的.你也许会说,这太简单了,写个循环,然后,让他自己去跑就行了.是的,你可以很顺手的用你的编程语言去写循环,如PHP.但是,你知道,这样做其实是改变了代码结构了,鬼知道会导致什么结果呢? 并且,我并不保证里面所有代码的意思,我都懂!那么,问题来了,在不改变原代码的前提下,怎样去循环这几个月的时间

  • 一个很简单的jquery+xml+ajax的无刷新树结构(无css,后台是c#)

    复制代码 代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data.Linq; using System.Xml; using System.Xml.Linq; namespace WebApplication3 { public

  • 很简单的Java断点续传实现原理

    原理解析 在开发当中,"断点续传"这种功能很实用和常见,听上去也是比较有"逼格"的感觉.所以通常我们都有兴趣去研究研究这种功能是如何实现的? 以Java来说,网络上也能找到不少关于实现类似功能的资料.但是呢,大多数都是举个Demo然后贴出源码,真正对其实现原理有详细的说明很少. 于是我们在最初接触的时候,很可能就是直接Crtl + C/V代码,然后捣鼓捣鼓,然而最终也能把效果弄出来.但初学时这样做其实很显然是有好有坏的. 好处在于,源码很多,解释很少:如果我们肯下功

  • 做了个flash对mc移动的控制,代码很简单:)

    复制代码 代码如下: 里面创建了4个MC,分别是zzcn_top_mc zzcn_end_mc zzcn_left_mc zzcn_right_mc . 很简单的..大家可以参考下哦..呵呵.. var place_x:Number = _xmouse; var place_y:Number = _ymouse; var sulv:Number = 6; zzcn_top_mc.onEnterFrame = function(){     this._x += (place_x - this._

  • 不能再简单的无闪刷新验证码原理很简单

    只有这一段事件触发语句全搞定 onclick='this.src="GifCode.asp#"+new Date().getTime()' // GifCode.asp 验证码的图片 事件: onclick='this.src="GifCode.asp#"+new Date().getTime()' 呵呵! 很简单很简单很简单,没想到吧 同理可以在ASP.NET PHP JSP 中运用

  • Linux并发执行很简单,这么做就对了

    &的并发功能 time for i in `grep server /etc/hosts | awk '{print $1}'`; do (ssh $i "echo 123; sleep 1; echo 456" &); done real 0m0.063s user 0m0.016s sys 0m0.004s xargs的并发功能 time grep server /etc/hosts | awk '{print $1}' | xargs -P 24 -I {} ss

  • C#很简单而又很经典的一句代码实例

    一.知识点 二.问题 如果以上四个问题,你很自信,那么以下,您就不要看了,因为我想说的东西真的很简单. 如果你开始怀疑自己,可以继续向下看.你自己到底真的理解吗??? 再看下面这段代码有没有问题? class Program { static void Main(string[] args) { Transform t = new Transform(); t.v.x = 1; t.ShowV(); Console.Read(); } } struct Vector { public float

  • 安装Redis就那么几步,很简单

    这段时间在做自己的网站,网站里用到了redis服务,redis的水很深,一时半会儿也摸不到底.这篇文章从安装开始,手把手教大家快速安装和使用redis. Redis是一种非关系型数据库(NoSQL),NoSQL是以key-value的形式存储,和传统的关系型数据库不一样,不一定遵循传统数据库的一些基本要求,比如说SQL标准,ACID属性,表结构等等,这类数据库主要有以下特点:非关系型的.分布式的.开源的.水平可扩展的. NoSQL使用场景:对数据高并发读写.对海量数据的高效率存储和访问.对数据的

  • 基于Python编写一个计算器程序,实现简单的加减乘除和取余二元运算

    方法一: 结合lambda表达式.函数调用运算符.标准库函数对象.C++11标准新增的标准库function类型,编写一个简单的计算器,可实现简单的加.减.乘.除.取余二元运算.代码如下: #include "pch.h" #include <iostream> #include <functional> #include <map> #include <string> using namespace std; int add(int i

  • IDEA中编写并运行shell脚本的实现

    IEDA中的bashsupport插件支持在IDEA中编写shell脚本文件,有友好的代码格式,支持自动补全,检查错误,并且配置完之后,还可以在IEDA中直接运行shell脚本.下面将一步一步演示插件的安装和配置. 打开IEDA,安装bashsupport插件  安装完之后,保持插件选中并切实enable的状态,如下图所示,然后重启IDEA. 安装git软件. https://www.git-scm.com/download/ 基本上直接安装全部默认就可以,不过要记住自己的安装目录. IDEA配

随机推荐