Shell简介
Shell是一种应用程序.提供一个界面,用户通过这个界面访问操作系统内核的服务.有很多不同的种类.比如
- Bourne Shell (/usr/bin/sh, /bin/sh)
- Bourne Again Shell (/bin/bash)
- C Shell (/usr/bin/csh)
- K Shell (/usr/bin/ksh)
- Shell for Root (/sbin/sh)
Shell脚本 & shell script指以shell编写的脚本程序 Shell编程跟C, PHP, python 编程一样,用你喜欢的文本编辑器写代码,用一个能解释执行的脚本解释器就可以了
本文的Shell脚本都是使用在日常工作中广泛使用的Bash,它是大多数Linux系统默认的Shell
Shell脚本
脚本文件的扩展名默认使用 sh, 扩展名不影响脚本.源代码的第一行一般都是 #!/bin/bash
, #!
是一个固定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell.
例子:
#!/bin/bash
echo "Hello World"
运行Shell脚本
可以有两种方法:
- 对sh文件添加可执行权限
chmod +x ./sh1.sh
, 然后使用./sh1.sh
来执行 - 直接运行解释器
/bin/sh sh1.sh
, 此时脚本文件不需要第一行#!/bin/bash
与众不同的运算符
算术运算符
运算符 | 说明 | 例子 |
---|---|---|
+, -, *, /, % | 看符号猜说明 | expr $a + $b , 或 $(( a / b )) |
== | 判断数值是否相等 | |
!= | 判断数值不相等 |
关系运算符
只支持数值运算
运算符 | 说明 |
---|---|
-eq | 判断是否相等 |
-ne | 不相等 |
-gt | > |
-lt | < |
-ge | >= |
-le | <= |
布尔运算符
运算符 | 说明 |
---|---|
! | 非运行, [[ ! true ]] 就是 false |
-o | 或 |
-a | 与 |
逻辑运算
运算符 | 说明 | ||
---|---|---|---|
&& | 逻辑AND | ||
逻辑OR |
字符串运算符
运算符 | 说明 |
---|---|
= | 判断是否相等, [ $a = $b ] 记得中间有空格 |
!= | 判断不相等 |
-z | 判断字符串长度是否为0, (== 0) |
-n | 判断字符串长度是否不为0 (!= 0) |
文件测试运算符
运算符 | 说明 |
---|---|
-b | 判断是否为块设备文件, [ -b $file ] |
-c | 字符设备文件 |
-d | 是否为目录 |
-f | 是否是普通文件 |
-g | 是否设置了SGID位 |
-k | 是否设置了Sticky Bit |
-p | 是否是有名管道 |
-u | 是否设置了SUID 位 |
-r | 文件是否可读 |
-w | 是否可写 |
-x | 是否可执行 |
-s | 文件不为空 |
-e | 是否存在(包括目录) |
一些例子
以下例子支持MAC系统
例子1: 获取本机IP地址,子网掩码,广播地址. 文件下载
#!/bin/sh
# 用于获取本机IP地址,子网掩码,广播地址
#
# 支持参数:
# s, -s: 带上表示不要显示说明信息,只显示获取到的信息
# 作者: Terry
# Email: jxd524@163.com
# Data: 2017-06-26 16:19
#
bSilent=0
while getopts "s" arg ; do
case $arg in
s )
bSilent=1
;;
esac
done
if [[ $bSilent -eq 0 ]]; then
echo "自动获取本机IP地址, MAC地址"
fi
ipInfo=( $(ifconfig | grep inet | grep netmask | grep broadcast | \
awk '{ \
split($0, ary, " "); \
for (i in ary){ \
if (i % 2 == 0) \
print ary[i] \
} \
}'))
len=`expr ${#ipInfo[@]} / 3`
if [ ${len} == 0 ]; then
echo "没有找到相关信息"
exit
fi
_Print() {
printf "%-20s%-20s%-30s\n" $1 $2 $3
}
if [[ $bSilent -eq 0 ]]; then
_Print "IP" "MASK" "Broadcast"
fi
i=0
while [[ ${len} > 0 ]]; do
ip=${ipInfo[$i]}
let "i += 1"
mask=${ipInfo[$i]}
let "i += 1"
broadcast=${ipInfo[$i]}
let "i += 1"
let "len -= 1"
_Print $ip $mask $broadcast
done
例子2: IP 地址的一些操作,子网掩码的计算等功能. 文件下载
#!/bin/shi
# IP 地址的一些操作,子网掩码的计算等功能
#
# 作者: Terry
# Email: jxd524@163.com
# Data: 2017-06-27 16:19
#
# 将整数转成IP址
# $1: 整形
# 返回: IP地址
function numToIp()
{
num=$1
a=$(( (num & 0xFF000000) >> 24 ))
b=$(( (num & 0x00FF0000) >> 16 ))
c=$(( (num & 0x0000FF00) >> 8 ))
d=$(( num & 0x000000FF ))
echo "$a.$b.$c.$d"
}
# 将点分十进制的IP转出整形
# $1: 点分十进制的IP
# 返回: IP地址的整形值
function ipToNum()
{
n=0
result=($( echo $1 | awk -F "." '{print $1, $2, $3, $4}' ))
if [[ ${#result[@]} == 4 ]]; then
n=${result[3]}
local bit=24
for (( i = 0; i < 3; i++ )); do
n=$(( n + (result[i] << bit) ))
bit=$(( bit - 8))
done
fi
echo $n
}
# 获取子网掩码的整形值
# $1: 支持以下类型
# 1: 16进制, eg 0xFFFFFF00
# 2: IP地址, eg 255.255.255.0
# 3: IP地址+位数 eg 255.255.255.0/24
# 返回: IP地址的整形值
function maskNum()
{
p=$1
n16=$( echo $p | grep -i '0x' )
if [[ ${#n16} != 0 ]]; then
#0xFFFFFF00
n=$( printf %d $n16 )
echo $n
return
fi
nBit=0
ip=$( echo $p | grep '/' )
if [[ ${#ip} != 0 ]]; then
#255.255.255.0/24
nBit=${p#*/}
nResult=0
if [[ $nBit -ge 8 && $nBit -le 30 ]]; then
i=31
while [[ $nBit -gt 0 ]]; do
nResult=$(( nResult + (1 << $i) ))
nBit=$(( nBit - 1 ))
i=$(( i - 1 ))
done
fi
echo $nResult
return
fi
echo $(ipToNum $p)
}
# 获取子网掩码的位数
# $1: 整形
# 返回: 几个1, 0表示无效的子网掩码
function maskNumBitCount()
{
mask=$1
nBit=0
i=31
for (( ; i >= 0; i-- )); do
if [[ $(( mask & (1 << i) )) != 0 ]]; then
nBit=$(( nBit + 1 ))
else
break
fi
done
for (( ; i >= 0; i-- )); do
if [[ $(( mask & (1 << i) )) != 0 ]]; then
echo 0
return
fi
done
echo $nBit
}
# 获取指定IP,子网掩码下的所有有效IP地址,去掉全0,全1
# $1: IP地址
# $2: 子网掩码
# 返回: IP整形数值
function allIntranetIps()
{
result=()
ip=$(ipToNum $1)
if [[ $ip == 0 ]]; then
ip=$1
fi
mask=$(maskNum $2)
if [[ $mask == 0 ]]; then
echo ${result[@]}
return
fi
nBaseIp=$(( ip & mask ))
nMaskBit=$(maskNumBitCount $mask)
nHostCount=$(( (1 << (32 - nMaskBit)) - 2 ))
for (( i = 0; i < $nHostCount; i++ )); do
result[i]=$(( nBaseIp + i + 1 ))
#echo $(numToIp $(( nBaseIp + i + 1 )))
done
echo ${result[@]}
}
ips=$(allIntranetIps '172.168.80.142' '0xffffff00')
for x in ${ips[@]}; do
echo $(numToIp $x)
done