Shell脚本基础知识及案例

来源:互联网 发布:unity3d 物体穿过地面 编辑:程序博客网 时间:2024/06/05 06:18

  Shell 脚本(即 Shell Script),Shell 脚本类似于 Windows/Dos 下的批处理,也就是将所需的各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要应用在 Linux 系统运维上,方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程语言编写的程序效率更高。由于它使用了 Linux/Unix 下的命令,因此想编写满足功能需求的 Shell 脚本,需要了解各种 Linux/Unix 命令,如 grep、sed、awk 等等。

Shell 脚本的第一行

  一般来说,Shell 脚本的第一行用于指定执行该脚本的解释器,如:

#!/bin/bash

“#!”符号读作“Sha-bang”,是 Shell 脚本的起始符号,后面紧跟解释器的路径,这里是 /bin/bash,此外我们还可能看到 /bin/sh、/bin/python 等等。

Shell 脚本的变量

  我们在 Shell 脚本中经常会遇到 $#$*$$$@$0$1$2$? 等形式的符号,要是不清楚其含义,就很容易懵逼,所以有必要记住以下这些规则。

$# —— 表示执行脚本传入参数的个数

$* —— 表示执行脚本传入参数列表

$$ —— 表示进程id

$@ —— 表示执行脚本传入所有参数

$0 —— 表示执行脚本名称

$1 —— 表示第一个参数

$2 —— 表示第二个参数

$? —— 表示脚本执行状态0正常,其他表示有错误

  
Shell 脚本中可以加入延时

  在 Shell 脚本中经常需要做一些延时处理,那么延时需要用到系统的 sleep 或 usleep。

sleep : 默认以秒(s)为单位
usleep : 默认以微秒(us)为单位

【 1s = 1000ms = 1000000us 】

此外,sleep 不仅可以用秒为单位,还可以指定延迟的单位,例如:

sleep 1s 表示延迟一秒
sleep 1m 表示延迟一分钟
sleep 1h 表示延迟一小时
sleep 1d 表示延迟一天

  值得一提的是,使用 sleep 或 usleep 进行延时是会阻塞的,假如我们在一个 Shell 脚本(姑且称为父脚本)中调用了另一个 Shell 脚本(子脚本),而子脚本恰好使用了延时,那么父脚本也会阻塞。如果这不是你想要的效果,请往下看(合理地使用 &)。

Shell 脚本的执行流程

  Shell 是单线程顺序执行的,要想实现“多线程”可以通过在后台运行多进程的方式来实现。在 bash 中,使用后台任务来实现任务的“多进程化”。在不加控制的模式下,不管有多少任务,全部都后台执行。也就是说,在这种情况下,有多少任务就有多少“进程”在同时执行。
  举个栗子:

# !/bin/bash  for  ((i = 0 ;i < 5 ;i ++ )); do {    sleep   3 ;echo  1 >> aa  &&  echo  " done! " } donewait cat aa | wc  - lrm aa

  上面这种情况下,程序顺序执行,每个循环3s,共需15s左右。输出结果如下:

$  time  bash test . sh  done !  done !  done !  done !  done !  5  real    0m15 . 030s user    0m0 . 002s sys     0m0 . 003s

进行“多进程化”改造:

# !/bin/bash for  ((i = 0 ;i < 5 ;i ++ )); do {    sleep   3 ;echo  1 >> aa  &&  echo  " done! " } & donewait cat aa | wc  - lrm aa

  这个改造实际上就在上面基础上多加了一个后台执行 & 符号,此时应该是5个循环任务并发执行,最后需要3s左右时间。输出结果如下:

$  time  bash test . sh  done !  done !  done !  done !  done !  5  real    0m3 . 011s user    0m0 . 002s sys     0m0 . 004s

  这里顺便说一下 wait 的作用。wait 是等待前面的后台任务全部完成才往下执行,否则程序本身是不会等待的,这样对后面依赖前面任务结果的命令来说就可能出错。例如上面 wc -l 的命令就报错:不存在 aa 这个文件。

案例:Shell 脚本找出某个进程并将其 kill

【test.sh】

#!/bin/bashNAME=$1PID=`ps -ef | grep "$NAME" | grep -v "$0" | grep -v "grep" | awk '{print $1}'`echo $PIDfor id in $PIDdokill -9 $idecho "killed $id"done

测试:为该 Shell 脚本设置执行权限,chmod a+x test.sh,执行 ./test.sh 进程名 即可。

1 0