您的位置:首页 > 运维架构 > Shell

Shell脚本基础知识及案例

2016-11-03 03:01 288 查看
  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! "
}
done
wait
cat aa | wc  - l
rm 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! "
} &
done
wait
cat aa | wc  - l
rm 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/bash

NAME=$1

PID=`ps -ef | grep "$NAME" | grep -v "$0" | grep -v "grep" | awk '{print $1}'`

echo $PID

for id in $PID
do
kill -9 $id
echo "killed $id"
done


测试:为该 Shell 脚本设置执行权限,
chmod a+x test.sh
,执行
./test.sh 进程名
即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: