Linux 命令行与 shell 脚本编程大全(第二版)简要阅读笔记。

看到哪儿就就记到哪,没有规律可循。

cron 时间表

全称 cron table ,* 通配符,dayofweek 可以使用 三字母格式(mon, tue, wed, thu, fri, sat, sun)

对应0-7 ,0, 7 为 sun。

每一月最后一天执行脚本的一种方式:

1
00 12 * * * if [ `date +%d -d tomorrow` = 01 ] ; then ; COMMAND

crontab -l 列出所有定时任务。

crontab -e 编辑用户自己的时间表,文件在 /var/spool/cron/ 目录下。

对于不要求使用精确时间的任务,可以在 /etc/cron.*ly 添加脚本。

hourly,monthly,daily。意如其名,复制到里面即可。

cron 惟一的问题是假定你 7x24 小时开机。

anacron 可以执行错过了的 cron 任务。

cron 时间戳文件在 /var/spool/anacron 下,作业表在 /etc/anacrontab 文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
0    2    *    *    6
*    *    *    *    *    *
-    -    -    -    -    -
|    |    |    |    |    |
|    |    |    |    |    + year [optional]
|    |    |    |    +----- day of week (0 - 7) (Sunday=0 or 7)
|    |    |    +---------- month (1 - 12)
|    |    +--------------- day of month (1 - 31)
|    +-------------------- hour (0 - 23)
+------------------------- min (0 - 59)

notes-for-shell-scripting-bible-1.jpg

在线验证 corntab 表达式

每次修改crontab file 后需要重启cron 吗?

一般来说,不需要,如果想确保已经生效,可以restart 一下。 https://stackoverflow.com/questions/10193788/restarting-cron-after-changing-crontab-file

突破最小执行时间 1 min的限制:

可以使用 sleep 实现:

1
2
3
4
5
6
7

crontab -l
# test
*/1 * * * * /usr/bin/date >> /home/rachpt/con-test.log
*/1 * * * * sleep 15; /usr/bin/date >> /home/rachpt/con-test.log
*/1 * * * * sleep 30; /usr/bin/date >> /home/rachpt/con-test.log
*/1 * * * * sleep 45; /usr/bin/date >> /home/rachpt/con-test.log

开机运行脚本

ubuntu 发行版默认开机运行级别 2 ,如果想改,需要自己创建 /etc/inittab文件。

0,关机;1 ,单用户模式;6 ,关机。2-5 ubuntu 不区分,red hat 区分。

不同发行版使用的 开机脚本(upstart script)路径不同,如

/etc/rc#.d

/etc/init.d

/etc/init.d/rc.d

定义自己的

/etc/initio.d/rc.local dabian 发行版

/etc/rc.local ubuntn 发行版

如果使用脚本,需要使用全路径名。

任务优先级

使用 nice renice 命令修改优先级。值 -20 – 20 ,越大优先级越小。

1
2
3
nice -d 10 ./test.sh

renice 12 -p 进程号

普通用户只能降低优先级,root 用户(或者 sudo)可以随意。

进程状态 S

符号 意义
D 可中断的休眠状态
R 运行状态
S 休眠状态
T 跟踪状态或停止状态
Z 僵化状态

模式空间与保持空间

一个经典案例,使用模式空间与保持空间实现反序。

1
sed -n '{1!G ; h ; %p }' filepath
命令 操作
h 模式空间 复制 到保持空间
H 模式 附加 到 保持
g 保持 复制到 模式
G 保持 附加到 模式
x 二者交换

negate 排除命令。排除末尾行,$! N ….

and 符号

使用&符号 代替 sed 匹配的内容。

1
2
3
4
echo "The cat sleeps in his hat" | sed 's/.at/"&"/g'

# 输出结果
The "cat" sleeps in his "hat"

上例中可以使用 子字符模块 实现,

1
2
3
echo "That furry cat is pretty, taht furry hat is pretty" | sed 's/hurry \(.at\)/\1/'
# 输出结果
That cat is pretty, taht hat is pretty

\1 替换第一个模块,\2 替换第二个,以此类推。

加倍行间距

一个简单的命令,加倍行间距。

1
sed '$!G' datafile

保持空间 在启动sed的时候默认只有一行空行。

但是有一个缺点,如果原文件中已经有些许空行,则会出现空行不均。

改进方法。

1
sed '/^$/d;$!G' datafile

先删除空行,然后加倍行。如果空行中有空格,需要例外匹配。

添加行号

简单的方法。

1
sed '=' datafile

但是 行号 与行不在同一行。改进。

1
sed '=' datafile | sed 'N; S/\n/ /'

说明,N 同时处理两行,将其中的 \n 换成 空格。

打印末尾几行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
rachpt@pc ~/desktop $ sed '{
> :start
> $q
> N
> 11,$D
> b start
> }' ms_castep.param
# 结果如下
geom_method : BFGS
fixed_npw : false
geom_modulus_est :      500.000000000000000  GPa
calculate_ELF : false
calculate_stress : true
popn_calculate : true
calculate_hirshfeld : true
calculate_densdiff : false
popn_bond_cutoff :        3.000000000000000
pdos_calculate_weights : false

$q 末行退出 b 跳转的循环,D 只输出模式空间中的第一行。

选择性删除空行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
rachpt@pc ~/desktop $ sed '/./,/^$/!d' test
# 结果如下
This is a header line

line 2
line 3

line 4

end of file
rachpt@pc ~/desktop $ 

/./,/^$/ 匹配 任意字符行可空行区间。