1. 如何在SHELL获取当天时间的月份和上个月的月份还有下个月的月份
上个月比较好写,减去当前日期,再减1天
# date -d "-1 days" -d "-`date +%d` days" +%m
09
------------------------------------------------------------
下个月就不好写咯
date里的1 month有问题
比如今天是10月31日
# date -d "1 month" +%m
12
变成12月了
# date +%m
10
获取当前月份
那么下个月只好写代码了:
now_month=`date +%m`
if [ $now_month -ne 12 ];then
echo nextmonth is `expr $now_month + 1`
else
echo nextmonth is 01
fi
2. shell脚本中如何取上个月比如现在201606,显示201605,试了多种都是显示当前
3. shell脚本计算时间
TIME_INPUT=`date -d "00:00" +%s`
通过时间戳来计算
nowtime=`date +%s`
shijiancha=`expr $nowtime - $TIME_INPUT`
if [ $shijiancha -gt 180 ];then
echo 3分钟前
else
if [ $shijiancha -lt -180 ];then
echo 3分钟后
fi
fi
4. 用shell脚本读取一个包含当前时间的文件,该文件的格式必须为第一行月,日,年,
先把当前时间写入该文件啊
命令:echo `date +"%Y-%m-%d %T"` >abc.txt
期中abc.txt是你的文件
此命令的结果:2015-12-17 09:09:25
再把顺序截取一下月日年
5. shell键盘获取一个日期,可查询其前N天后N天!!要求,不是用date自带的命令方法,考虑平年闰年跨年跨月
序
最近努力学习新知识,在公司内网上阅读一些优秀文章,但是发现这些文章:是通过通过flash控件展示,并且不提供无法下载地址(类似《网络文库》)。一次忍了,两次再忍了,三次就无法忍受:都在我电脑上展示了,这么做就是恶心人了。。。。
于是花了大半天时间,使用mac上自带软件Automator,从零开始完成了自己的工具:《连续抓图导出PDF》。
实现原理:自动截屏、翻页=》merge生成PDF文档。(感兴趣的人,可以下载附件看看源码)
在写这个脚本过程中,本以为会很快,但是还是碰到了不少问题;于是就记录并分享出来。
首先:最基本用法,可以直接参考Automator帮助,本文章只写自认为容易忽略或者难点的几个地方。
变量使用
变量新建就不说了;这里主要说变量再控件上使用,几种方法(有的方法只对部分控件有用):
从下拉列表直接选择“变量”
将“变量”拖进区域
当然你也可以,抛弃使用已存在的变量,直接通过下拉框选择一个“新建变量”。
“输入变量名”弹出提示,“回车”选择
最后,如果上面三种方法你尝试都不行的话,基本上可以宣告,那个是不支持变量的。
比如,LOOP的“次数”,是不支持变量的:
脚本
脚本使用
Automator脚本支持:shell脚本(bash、perl、python、ruby等)、appleScript、javascript几种,你可以选择不同的脚本来运行。
脚本参数传递
脚本和变量之间,是无法直接获取或设置的
“变量”值传递到脚本
– shell脚本
获取到的输入:只能是通过输入的一行一行的字符串
也即如果,想获取变量值的话,可以通过,“获得变量的值”控件来输出值,然后传递到脚本然后再读取。
如:下面是获取“页数”、“URL”、“临时文件夹”三个变量值到输出,然后传递给perl脚本。1234
– AppleScript脚本
AppleScript的输入不是一行一行的字符串,貌似是键值队(还不熟悉这块),结果没搞懂如何传递的变量——搞懂后,再补充。
于是我考虑的解决方案是:通过分隔符“|”将输入的多行转换成一行,然后在AppleScript进行反转。的确是有些trick -_-!——不过后来查资料发现,也有人这么整。123
perl代码:
@input = ();while (<>) { $_=~s/(^s*)|(s*$)//g; push(@input,$_);
}print join "|" ,@input;123456
AppleScript代码:
on run input set myArray to my theSplit((item 1 of input) as string, "|") set outputPath to item 1 of myArray set pagenum to item 2 of myArray as number
set myurl to item 3 of myArray set tempDir to item 4 of myArray
return myArrayend runon theSplit(theString, theDelimiter) -- save delimiters to restore old settings
set oldDelimiters to AppleScript's text item delimiters
-- set delimiters to delimiter to be used
set AppleScript's text item delimiters to theDelimiter -- create the array
--set theArray to every text item of theString
set theArray to text items of theString -- restore the old setting
set AppleScript's text item delimiters to oldDelimiters -- return the result return theArrayend
脚本结果,设置到“变量”中
脚本中的变量,是无法设置到脚本中,怎么办呢?其也只能通过脚本输出结果,然后“设定变量的值”控件,对变量进行设置。
- - 设置一个变量
注意:这里有一个问题,如果脚本输出的是多行,其实只把第一行字符串,赋值到“变量”中
设置多个变量
- $count=0;while(<>){ print $_ if $count >0 ;
- $count = $count + 1 ;
- }12345
- on run {input, parameters} --
- set timeoutSeconds to 0
- set uiScript to "keystroke "a" " --标注,注意这行代码
- my doWithTimeout(uiScript, timeoutSeconds) return inputend runon doWithTimeout(uiScript, timeoutSeconds) set endDate to (current date) + timeoutSeconds repeat
- try
- run script "tell application "System Events"
- " & uiScript & "
- end tell"
- exit repeat
- on error errorMessage if ((current date) > endDate) then
- error "Can not " & uiScript end if
- end try
- end repeatend
- set uiScript to "keystroke "a" "1
- set uiScript to "key code 124 "1
- set uiScript to "key code 0 "1
- set uiScript to "key code 0 using {shift down} "1
- $ grep '^ *kVK' /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h|tr -d ,|while read x y z;do printf '%d %s %s ' $z $z ${x#kVK_};done|sort -n1
- set uiScript to "key code 124 using {control down, option down, command down,shift down}" --control+option+command+right+shift1
只能从脚本开头循环
循环策略支持:
A)次数/时间,但是无法通过变量控制
B)询问方式
试想一下,你就是需要从中间块循环,但是他非要从开头开始,你是无法选择的,这是个多么想哭的事情。- on run input set myArray to my theSplit((item 1 of input) as string, "|") set outputPath to item 1 of myArray set pagenum to item 2 of myArray as number
- set myurl to item 3 of myArray set tempDir to item 4 of myArray delay 10
- set mycount to 1000 as number
- repeat
- run_workflow(tempDir & "/" & (mycount) & ".pdf", "/Users/xxxx/Desktop/test2/自动截频.workflow") if pagenum ≤ 1 then
- exit repeat
- end if
- set pagenum to pagenum - 1
- set mycount to mycount + 1
- --按下右键
- set timeoutSeconds to 2
- set uiScript to "keystroke (ASCII character 29) "
- my doWithTimeout(uiScript, timeoutSeconds) end repeat
- delay 1 return myArrayend run--执行workflowon run_workflow(inputVars, workflowPath) set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, linefeed} set theInputsList to inputVars as text
- set AppleScript's text item delimiters to tid set cmd to "automator -i '" & theInputsList & "' " & workflowPath return do shell script cmdend run_workflowon theSplit(theString, theDelimiter) -- save delimiters to restore old settings
- set oldDelimiters to AppleScript's text item delimiters
- -- set delimiters to delimiter to be used
- set AppleScript's text item delimiters to theDelimiter -- create the array
- --set theArray to every text item of theString
- set theArray to text items of theString -- restore the old setting
- set AppleScript's text item delimiters to oldDelimiters -- return the result return theArrayend theSpliton doWithTimeout(uiScript, timeoutSeconds) set endDate to (current date) + timeoutSeconds repeat
- try
- run script "tell application "System Events"
- " & uiScript & "
- end tell"
- exit repeat
- on error errorMessage if ((current date) > endDate) then
- error "Can not " & uiScript end if
- end try
- end repeatend 2425262728293031323369
但是如果要设置多个变量值,咋办?
于是又是一个trick方法来了,利用上面“只会把第一行赋值给变量”的机制,通过“漏斗”方式逐个对变量进行赋值:
如上图,依次对“导出路径”、“页数”等多个变量进行逐个复制。
其中perl代码作用是:过滤第一行字符串:
键盘录制&鼠标录制
Automator提供“录制”功能,位于右上角:
注意如果你使用录制功能,需要mac再偏好设置里,设置一下“允许Automator控制你的电脑”,这样在运行时才有用:
但是实际操作起来,我碰到了下面两个问题:
1、鼠标录制,总是不准
2、键盘录制,则永远也没有录制上去
第一个问题,我没有找到很好办法;最后没有使用;
第二个问题,不是录入,而是写代码,通过appleScript来实现:
键盘操作
脚本代码是:
接下来,看看键盘操作(均是修改,标注的那一行)几种情况解决方案:
普通字符
普通字符,比较简单,使用keystroke ,输入字符就可以,比如输入”a”字符:
特殊字符
对于一些特殊字符,没有特殊ASCII码,比如:上、下、左、右键。因此可以考虑另外一个通过“键值”(即操作系统对按键的虚拟值)来实现,key code :
比如:“右”按键的代码是:
当然,key code 也可以输入普通字符,如:
“a” 按键代码是:
“A”按键代码是:
mac系统的虚拟键值,可以通过终端命令执行下面命令查询到:
或者你直接查下“附1-key code 表”也行:
组合键
上两个方法,都可以配合组合键进行使用:
循环
Automator对于系列处理动作的流程,制作非常简单,仅仅需要拖拽基本就可以实现。
但是在分支、循环等这种逻辑上,处理起来要复杂很多。 基本稍微复杂一点的都需要脚本配合才可以的。
简单循环
Automator只提供了简单的“Loop”循环控件,这个循环控件可控执行很差,因为:
复杂循环
那么对于复杂的循环怎么处理?
Automator支持workflow的调用,因此如果你需要循环的话一种解决方案就是:将需要循环块的部分,写成workflow1,然后再主workflow通过脚本控制workflow1的循环。
workflow开始准备工作调用workflow1是否结束?结束yesno
注意:新建workflow1时,选择“工组流程”:
这里实现主要有两个问题:
1、workflow之间的变量是无法共享的(至少现在我发现是这样的)。它也只能想字符串一样传递。
但是这个问题:上面脚本使用一节中的“多变量的赋值”方法可以解决。
2、如何脚本调用,workflow?
通过 do shell script cmd,进行执行cmd命令调用,但是这里有一个问题就是:命令执行是不等待结束立即返回的(实现方法是新起进程执行)——目前还没有找到能够等待返回的方法。
附
附1-key code 表
十进制
十六进制
按键
0 0x00 ANSI_A
1 0x01 ANSI_S
2 0x02 ANSI_D
3 0x03 ANSI_F
4 0x04 ANSI_H
5 0x05 ANSI_G
6 0x06 ANSI_Z
7 0x07 ANSI_X
8 0x08 ANSI_C
9 0x09 ANSI_V
10 0x0A ISO_Section
11 0x0B ANSI_B
12 0x0C ANSI_Q
13 0x0D ANSI_W
14 0x0E ANSI_E
15 0x0F ANSI_R
16 0x10 ANSI_Y
17 0x11 ANSI_T
18 0x12 ANSI_1
19 0x13 ANSI_2
20 0x14 ANSI_3
21 0x15 ANSI_4
22 0x16 ANSI_6
23 0x17 ANSI_5
24 0x18 ANSI_Equal
25 0x19 ANSI_9
26 0x1A ANSI_7
27 0x1B ANSI_Minus
28 0x1C ANSI_8
29 0x1D ANSI_0
30 0x1E ANSI_RightBracket
31 0x1F ANSI_O
32 0x20 ANSI_U
33 0x21 ANSI_LeftBracket
34 0x22 ANSI_I
35 0x23 ANSI_P
36 0x24 Return
37 0x25 ANSI_L
38 0x26 ANSI_J
39 0x27 ANSI_Quote
40 0x28 ANSI_K
41 0x29 ANSI_Semicolon
42 0x2A ANSI_Backslash
43 0x2B ANSI_Comma
44 0x2C ANSI_Slash
45 0x2D ANSI_N
46 0x2E ANSI_M
47 0x2F ANSI_Period
48 0x30 Tab
49 0x31 Space
50 0x32 ANSI_Grave
51 0x33 Delete
53 0x35 Escape
55 0x37 Command
56 0x38 Shift
57 0x39 CapsLock
58 0x3A Option
59 0x3B Control
60 0x3C RightShift
61 0x3D RightOption
62 0x3E RightControl
63 0x3F Function
64 0x40 F17
65 0x41 ANSI_KeypadDecimal
67 0x43 ANSI_KeypadMultiply
69 0x45 ANSI_KeypadPlus
71 0x47 ANSI_KeypadClear
72 0x48 VolumeUp
73 0x49 VolumeDown
74 0x4A Mute
75 0x4B ANSI_KeypadDivide
76 0x4C ANSI_KeypadEnter
78 0x4E ANSI_KeypadMinus
79 0x4F F18
80 0x50 F19
81 0x51 ANSI_KeypadEquals
82 0x52 ANSI_Keypad0
83 0x53 ANSI_Keypad1
84 0x54 ANSI_Keypad2
85 0x55 ANSI_Keypad3
86 0x56 ANSI_Keypad4
87 0x57 ANSI_Keypad5
88 0x58 ANSI_Keypad6
89 0x59 ANSI_Keypad7
90 0x5A F20
91 0x5B ANSI_Keypad8
92 0x5C ANSI_Keypad9
93 0x5D JIS_Yen
94 0x5E JIS_Underscore
95 0x5F JIS_KeypadComma
96 0x60 F5
97 0x61 F6
98 0x62 F7
99 0x63 F3
100 0x64 F8
101 0x65 F9
102 0x66 JIS_Eisu
103 0x67 F11
104 0x68 JIS_Kana
105 0x69 F13
106 0x6A F16
107 0x6B F14
109 0x6D F10
111 0x6F F12
113 0x71 F15
114 0x72 Help
115 0x73 Home
116 0x74 PageUp
117 0x75 ForwardDelete
118 0x76 F4
119 0x77 End
120 0x78 F2
121 0x79 PageDown
122 0x7A F1
123 0x7B LeftArrow
124 0x7C RightArrow
125 0x7D DownArrow
126 0x7E UpArrow
6. 请教如何在shell脚本中得到系统当前时间
在shell脚本里常常需要获取系统时间来处理某项操作,今天系统的学习了一下如何获取系统时间。记录如下:
linux的系统时间在shell里是可以直接调用系统变量的如:
获取今天时期:`date +%Y%m%d` 或 `date +%F` 或 $(date +%y%m%d)
命令输出结果如下:
[root@centi-C sh]# date +%Y%m%d
20120727
[root@centi-C sh]# date +%F
2012-07-27
[root@centi-C sh]# date +%y%m%d
120727
获取昨天时期:`date -d yesterday +%Y%m%d` 也可以写成`date -d -1day +%Y%m%d`
[root@centi-C sh]# date -d yesterday +%Y%m%d
20120726
[root@centi-C sh]# date -d yesterday +%F
2012-07-26
[root@centi-C sh]# date -d -1day +%y%m%d
120726
[root@centi-C sh]# date -d -1day +%Y%m%d
20120726
获取前天日期:`date -d -2day +%Y%m%d`
依次类推比如获取10天前的日期:`date -d -10day +%Y%m%d`
或n天前的 `date -d "n days ago" +%y%m%d`
明天:`date -d tomorrow +%y%m%d`
注意以上中间有空格
至于你需要什么样的日期时间格式,就需要应用相关的时间域参数来实现咯
相关时间域如下:
% H 小时(00..23)
% I 小时(01..12)
% k 小时(0..23)
% l 小时(1..12)
% M 分(00..59)
% p 显示出AM或PM
% r 时间(hh:mm:ss AM或PM),12小时
% s 从1970年1月1日00:00:00到目前经历的秒数
% S 秒(00..59)
% T 时间(24小时制)(hh:mm:ss)
% X 显示时间的格式(%H:%M:%S)
% Z 时区 日期域
% a 星期几的简称( Sun..Sat)
% A 星期几的全称( Sunday..Saturday)
% b 月的简称(Jan..Dec)
% B 月的全称(January..December)
% c 日期和时间( Mon Nov 8 14:12:46 CST 1999)
% d 一个月的第几天(01..31)
% D 日期(mm/dd/yy)
% h 和%b选项相同
% j 一年的第几天(001..366)
% m 月(01..12)
% w 一个星期的第几天(0代表星期天)
% W 一年的第几个星期(00..53,星期一为第一天)
% x 显示日期的格式(mm/dd/yy)
% y 年的最后两个数字( 1999则是99)
% Y 年(例如:1970,1996等)
注意:只有超级用户才有权限使用date命令设置时间,一般用户只能使用date命令显示时间。
添加一个练习脚本,功能:
在每月第一天备份并压缩/etc目录的所有内容,存放在/root/bak目录里,且文件名为如下形式yymmdd_etc,yy为年,mm为月,dd为日。Shell程序fileback存放在/usr/bin目录下。
#/bin/bash
#filebak
#file executable: chmod 755 filebak
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
bakdir="/root/bak/"
filename="`date +%y%m%d`_etc.tar.gz"
if [ ! -x "$bakdir" ];then
mkdir $bakdir
fi
cd $bakdir
tar cvfz $filename /etc
或使用crontab -e 命令添加定时任务:
0 1 * * * /bin/sh /usr/bin/fileback
7. shell 如何判读当前日期是否是,当月的第一天
用一个简单脚本判断日期是否是1号即可,脚本如下:
#!/bin/bash
#取得今天的日
DAY=`date +%d`
#判断是否为1号
if [ "$DAY" = 01 ];
then
echo yes
else
echo no
fi
8. linux中,怎么通过shell语句获取当前日期,输出格式要求20111224.
获得当天的日期:date +%Y%m%d,输出: 20181130。
需要使用今天之前或者往后的日期,这时可以使用date的 -d参数:
1、获取明天的日期:date -d next-day +%Y%m%d。
2、获取昨天的日期:date -d last-day +%Y%m%d。
3、获取上个月的年和月:date -d last-month +%Y%m。
4、获取下个月的年和月:date -d next-month +%Y%m。
5、获取明年的年份:date -d next-year +%Y。
(8)shell脚本查询当月的天数扩展阅读
linux的系统时间在shell里是可以直接调用系统变量的如:
获取今天时期:`date +%Y%m%d` 或 `date +%F` 或 $(date +%y%m%d)
命令输出结果如下:
[root@centi-C sh]# date +%Y%m%d
20120727
[root@centi-C sh]# date +%F
2012-07-27
[root@centi-C sh]# date +%y%m%d
120727