本文不详细讲解,理论和用法。希望通过几个Shell脚本案例快速上手Shell脚本的编写
变量的声明
变量名=变量值
删除变量
unset 变量名
将命令的输出赋值给变量
变量名=`command`
与输入输出有关的文件描述
文件描述符 | 文件名 | 类型 | 硬件 |
---|---|---|---|
0 | stdin | 标准输入文件 | 键盘 |
1 | stdout | 标准输出文件 | 显示器 |
2 | stderr | 标准错误输出文件 | 显示器 |
符号 | 说明 |
---|---|
$$ | Shell 本身的PID |
$! | Shell 最后运行的后台Process的PID |
$? | 最后运行的命令的结束代码(返回值),即执行上一条指令的返回值(显示最后命令的退出状态。0表示没有错,其他任何值表明有错误) |
$- | 使用Set命令设定Flag一览 |
$* | 所有参数列表 |
$@ | 所有参数列表 |
$# | 添加到Shell 的参数个数 |
$0 | Shell本身的文件名 |
$1- $n | 添加到Shell的各参数值,序号表示第几个参数 |
文件表达
符号 | 说明 |
---|---|
-e filename | 如果filename存在,则为真 |
-d filename | 如果filename为目录,则为真 |
-f | filename 为常规未见,则为真 |
-L | filename 为符号链接,则为真 |
-r | filename 可读,则为真 |
-w | filename 可写,则为真 |
-x | filename 可执行,则为真 |
-s | filename 文件长度不为0,则为真 |
-h | 如果文件是软链接,则为真 |
整数变量表达式
符号 | 说明 |
---|---|
-eq | 等于 |
-ne | 不等于 |
-gt | 大于 |
-ge | 大于等于 |
-lt | 小于 |
-le | 小于等于 |
#! /bin/bash
ls *.c > execfile
while read LINE
do
chmod +x ${LINE}
done<execfile
这个程序表明从execfile
中读入数据,并将循环得到的每行数据赋值给变量LINE。然后将其中的每个以.c
结尾的文件赋予可执行权限。
while 版本
#!/bin/bash
clear_file(){
cat /dev/null > iplog.txt
}
i=1
MaxRange=20
clear_file
while [ $i -le ${MaxRange} ]
do
ping -c 2 -i 0.3 -W 1 192.168.4.${i} &>/dev/null
if [ $? -eq 0 ];then
echo "192.168.4.${i}" >> iplog.txt
else
echo "192.168.4.${i} is down"
fi
let i++
done
这里比较费解的就是 $?,代表的其实就是上一条指令的返回值(显示最后命令的退出状态,0表示没有错误,其他任何值表明有错误)。
这样其实就好理解上面这段脚本的运作原理了。
多进程版本
#!/bin/bash
clear_file(){
cat /dev/null > iplog.txt
}
i=1
myping(){
ping -c 2 -i 0.3 -W 1 $1 &>/dev/null
if [ $? -eq 0 ];then
echo "${1} is up"
else
echo "${1} is down"
fi
}
for i in {1..20}
do
myping 192.168.4.${i} &
done
使用&符号,将执行的函数放入后台执行
这样做的好处就是不需要等待ping第一台主机的回应,就可以继续并发ping第二台主机,依次类推。
可以观察运行的输出多进程版本明显快于单进程版本
#!/bin/bash
#查看有多少远程的 IP 正在连接本机(不管是通过 ssh 还是 web 还是 ftp都统计)
#使用 ``netstat -atn`` 可以查看本机所有连接的状态,-a 查看所有
#-t 仅显示 tcp 连接的信息, -n 数字格式显示
#Local Address (第四列是本机的IP和端口信息)
#Foreign Address (第五列是远程主机的IP和端口信息)
#使用awk 命令仅显示第5列数据, 再显示第 1 列 IP 地址的信息
#sort 可以按数字大小排序,最后使用 uniq 将多余重复的删除,并统计重复的次数
netstat -atn | awk '{print $5}' | awk '{print $1}' | sort -nr | uniq -c
#!/bin/bash
printChess(){
#打印国际象棋棋盘
#设置两个变量 i、j 分别代表行和列
#棋盘的规则其实就是相邻的不同颜色
#使用echo -ne 打印色块,并且打印完成色块后不自动换行,在同一行继续输出其他色块
for i in {1..8}
do
for j in {1..8}
do
sum=$[i+j]
if [ $[sum%2] -eq 0 ];then
echo -ne "\033[46m \033[0m"
else
echo -ne "\033[47m \033[0m"
fi
done
echo
done
}
printChess
#!/bin/bash
# programRunning
checkNumber(){
case $1 in
start)
echo "starting"
;;
stop)
echo "stoping"
;;
test)
echo "is testing"
;;
*)
echo "Usage: {start|stop}"
;;
esac
}
a=
read -p "please select option: " a
checkNumber $a
#!/bin/bash
PID=
get_pid(){
PID=`ps -ef | grep root | grep ywh | awk '{print $2}'`
}
get_pid
echo $PID