shell变量
查看linux下面的shell
cat /etc/shells
切换linux下面的shell
usermod -s /bin/tcsh test (其中test为用户)
chsh -s /bin/bash test
查看用户的bash
grep test /etc/passwd
命令的查找路径于顺序
当我们输入一个命令的时候shell如何去查找命令然后去执行?
这是通过环境变量 PATH 来进行搜索的。
执行脚本的方式
1、新建文件
mkdir /root/shell/day1
2、添加可执行语句
chmod +x /root/shell/day1
3、执行脚本的方式
1、文件需要赋予可执行文件的权限
/root/shell/
./day1(绝对路径)
../shell(相对路径)
2、不需要赋予可执行的权限
bash 脚本文件名
bash /root/shell/day1
source 脚本文件名 #不会启动子进程,通过pstree查看进程树
先执行解释器然后让这个解释器去读取然后执行这个脚本文件内容,所以不需要可执行权限。
4、脚本规范
#!脚本声明(使用哪种解释器解释代码)
注释信息(步骤、用途),以#开始的为注释
可执行语句
#! /bin/bash
echo "Hello World"
shell变量
环境变量:有效作用域中变化的量,通常变量和值一一对应。
1、定义变量
declare tmp :
declare 用于声明变量 tmp为变量 =赋值运算
例:tmp=xiaoming
2、使用变量
使用echo
命令和$
符号 ($
符号用于表示引用一个变量的值,初学者经常忘记输入)
例 :
tmp=xiaoming echo $tmp 显示结果为xiaoming
或者
tmp=xiaoming echo ${tmp} {}帮助解释器识别变量的边界
变量可以多次使用,但是被覆盖就不可以使用了。
撤销变量
unset tmp
脚本执行的过程中变量是有效,脚本执行完变量就会取消。
echo $x6.5
.5
变量为x6但是没有定义,所以取到.5, bash脚本以特殊字符分割,所以把x6为一个整体
注意:并不是任何形式的变量名都是可用的,变量名只能是英文字母、数字或者下划线,且不能以数字作为开头。
3、只读变量
使用readonly命令可以将变量定义为只读变量,只读变量的值不能被改变。
#!/bin/bash
myUrl="https://www.google.com"
readonly myUrl
myUrl="https://www.runoob.com
运行脚本,结果如下:
/bin/sh: NAME: This variable is read only.
read 从键盘读入变量值完成赋值
语法:read [-p "提示信息“] 变量名
-p 可选,-t可指定超时秒数,-s设置是否在终端显示输入的内容
[root@localhost shell]# cat day1
# !/bin/bash
# test positional parameters
read -p "your name is :" name
read -p "your cipher:" password
useradd "$name"
echo "$password" | passwd --stdin "$name"
[root@localhost shell]# read -p "please your name:" iname
please your name:long
[root@localhost shell]# echo $iname
long
变量类型
运行shell时,会同时存在三种变量:
1) shell变量
shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
2) 环境变量
所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。又系统维护。
3) 局部变量
局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
位置变量(bash内置变量,存储脚本执行时候的参数)
自定义变量(用户自主设置)
预定义变量(bash内置变量,可以调用但是不能被赋值或修改)
环境变量
存储在/etc/profile 或者 ~/.bash_profile
命令env可以列出所有的环境变量
常见环境变量
PATH / PWD / USER / UID / HOME / SHELL
echo $PATH
ehco $UID
全局变量在当前的shell以及子shell环境中均有效
[root@localhost shell]# x=11
[root@localhost shell]# sh
sh-4.4# echo $x
sh-4.4# exit
exit
[root@localhost shell]# export x=11
[root@localhost shell]# sh
sh-4.4# echo $x
11
局部变量
新定义的变量默认自在当前shell环境中有效,无法再子shell中使用
位置变量
存储脚本执行时的参数
使用$n表示,n为数字序列号
$1 、
2.....
2.....
2.....{10}、${11}…
实例1、常见位置参数使用
以下实例我们向脚本传递三个参数,并分别输出,其中 $0 为执行的文件名(包含文件路径):
#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
执行脚本
$ chmod +x test.sh
$ ./test.sh 1 2 3
Shell 传递参数实例!
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3
我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推。。。。
实例2:使用脚本修改用户名的密码
[root@localhost shell]# cat day1
vim day1
# !/bin/bash
# test positional parameters
useradd "$1"
echo "$2" | passwd --stdin $1
[root@localhost shell]# bash day1 root 123
useradd: user 'root' already exists
Changing password for user root.
passwd: all authentication tokens updated successfully.
使用grep root /etc/passwd 查看是否修改成功
预定义变量
用来保存脚本程序的执行信息
- 直接使用这些变量
- 不能直接变量赋值
变量名
$0 当前所在的进程或脚本名
$$ 当前运行进程的PID号
$? 上一条命令执行后的返回状态,0表示正常,1或其他值表示异常
$# 已加载的位置变量的个数
$* 所有位置变量的值
实例1、测试预定义变量
[root@localhost shell]# bash day1 1 2 3 4
day1
1 2 3 4
4
21727
变量的扩展
区分三种定界符
双引号 " "
:允许扩展,以$
引用其他变量
单引号' '
:禁用扩展,即便$
也视为普通字符
反引号 `` :将命令的执行输出作为变量值,&()等于反引号等效
[root@localhost shell]# touch a b c
[root@localhost shell]# touch "a b c"
[root@localhost shell]# ls
a 'a b c' b c day1
[root@localhost shell]# echo "$USER id is $UID"
centos id is 0
[root@localhost shell]# echo 'USER id is $UID'
USER id is $UID
单引号和双引号的区别:
单引号屏蔽特殊符号,双引号不会屏蔽特殊符号。
将输出内容作为变量
[root@localhost shell]# test1=$(grep root /etc/passwd)
[root@localhost shell]# echo $test1
root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin
四则运算
加法 :num1+num2
减法:num1-num2
乘法:num1*num2
除法:num1/num2
取余:num1 %num2
实例1:计算值
实例2:Bash小数计算
[root@localhost shell]# echo "scale=2; 10/2" |bc
5.00
[root@localhost shell]# echo "scale=2; 10+4" | bc
14
调整输出的演示
[root@localhost shell]# echo -n "hello world"
hello world[root@localhost shell]# echo -e "\033[32m ok \033[0m"
ok
这里的ok显示为绿色,如果没有\033[0m 后面的输出全为绿色
实例3:输出计算机得硬件信息
# !/bin/bash
# test positional parameters
echo -e "\033[32m-------your informathion---\033[0m"
echo -e "\033[32m-----ifconfig informathion: \033[0m"
ifconfig ens32 | grep "inet"
echo -e "\033[32m meminfo : \033[0m"
grep MemAvailable /proc/meminfo
echo -e "\033[32m disk : \033[0m"
df -h /
echo -e "\033[32m CPU information: \033[0m"
grep "model name" /proc/cpuinfo
实例4:计算相对应的面积
[root@localhost shell]# cat day1
# !/bin/bash
# test positional parameters
# A=1/2bh
read -p "pelease input bottom:" bottom
read -p "pelease input hight:" hight
A=$(echo "scale=1 ;1/2*$bottom*$hight" | bc)
echo -e "\033[32m S=$A \033[0m"
Shell 字符串
字符串基本
字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号
单引号
str='this is a string'
单引号字符串的限制:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
双引号
your_name='runoob'
str="Hello, I know you are \"$your_name\"! \n"
echo -e $str
双引号的优点:
双引号里可以有变量
双引号里可以出现转义字符
字符串处理
字符串截取
语法格式
${变量:起始位置:长度} #从0开始起始位置
[root@root shell]# ceshi=123456
[root@root shell]# echo ${#ceshi} #统计长度
6
[root@root shell]# echo ${ceshi:0:3}
123
[root@root shell]# echo ${ceshi:2:3}
345
[root@root shell]# echo ${ceshi:2}
3456
[root@root shell]# echo ${ceshi:3:-2}
4
字符串替换
语法格式
替换一个结果
${变量/旧字串/新字串}
替换全部结果
${变量//旧字串/新字串}
实例1:字符替换
[root@root shell]# echo ${ceshi/1/x}
x112344
[root@root shell]# echo ${ceshi//1/x}
xxx2344
从左向右,最短匹配删除
${变量#关键词}
#对变量掐头不会改变变量变量原有的值
从左向右,最长匹配删除
${变量## 关键词}
[root@root shell]# A=` head -1 /etc/passwd `
[root@root shell]# echo $A
root:x:0:0:root:/root:/bin/bash
[root@root shell]# echo ${A#*:}
x:0:0:root:/root:/bin/bash
[root@root shell]# echo ${A##*:}
/bin/bash
从右向左,最短匹配删除
${变量%关键词}
#对变量去除尾不会改变变量原有的值
从右向左,最长匹配删除
${变量%%关键词}
[root@root shell]# echo $A
root:x:0:0:root:/root:/bin/bash
[root@root shell]# echo ${A%:*}
root:x:0:0:root:/root
[root@root shell]# echo ${A%%:*}
root
实例2、批量替换文件名称
替换前
[root@root shell]# ls
{a.b.c.d.e.f}.txt day day2 renmae1.sh
#! /bin/bash
for i in $(ls *.txt)
do
mv $i ${i%.*}.doc
done
替换后
[root@root shell]# ls
{a.b.c.d.e.f}.doc day day2 renmae1.sh
实例3、所有文件名称替换
#! /bin/bash
for i in $(ls *.$1)
do
mv $i ${i%.*}.$2
done
变量返回
变量有值,则返回该变量的值
变量无值,则返回初始值
语法格式
${变量:-关键词}
[root@root shell]# X=123
[root@root shell]# echo ${X:-xyz}
123
[root@root shell]# echo ${ABC:-xyz}
xyz
实例3、修改用户密码
#! /bin/bash
read -p "please input your name " iname
if [ -z "$iname" ] ; then
echo -e "\033[32m Don input name ,exit \033[0m"
exit
fi
read - p "please input your message:" ipass
ipass=${ipass:-qwe}
useradd "$iname"
echo "$ipass" | passwd --stdin "$iname"
实例4:输出随机密码
#! /bin/bash
#定义变量:10个数字+52字母#用随机数对62取余数,返回结果为【0-61】
key="abcdefghijklmnopqstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
pass=""
for i in {1..10}
do
num=$[RANDOM%${#key}]
tmp=${key:num:1}
pass=${pass}${tmp}
done
echo $pass
随机密码2:
使用命令生成
uuidgen
openssl rand -base64 10
随机密码3:
使用随机设备文件(dev/random /dev/urandom)
tr 命令可以对数据进行替换、删除等操作
-c:取反 、 -d :删除
tr -cd -cd "0-9a-zA-Z" < /dev/urandom | head -c 10
#删除随机数据不是数字、小写字母、大写字母的数据
#在截取出来的字串汇总提取前10个字符
Shell 数组
用来存储多个数据的集合,bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
类似于 C 语言,数组元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0。
定义数组
在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:
数组名=(值1 值2 ... 值n)
array_name=(value0 value1 value2 value3)
或者
array_name[0]=value0
array_name[n]=valuen
读取数组
读取数组元素值的一般格式是:
${数组名[下标]}
valuen=${array_name[n]}
定义数组() ,读取数组[],使用数组变量{}
条件测试
1、数值比较
[root@localhost centos]# [ 3 -lt 8 ]
[root@localhost centos]# echo $?
0
显示为0时为真
2、字符比较
[root@localhost centos]# [ -z "$TT" ]
[root@localhost centos]# echo $?
0
[root@localhost home]# x=long
[root@localhost home]# y=fei
[root@localhost home]# [ $x == $y ]
[root@localhost home]# echo $?
1
注意:
[root@localhost home]# [ $long === $fei ]
[root@localhost home]# echo $?
0
注意:使用中括号时必需使用每一个参数都必须使用空格
3、数字和变量对比
4、对文件和目录做比较
[root@localhost centos]# [ -e /etc/ ]
[root@localhost centos]# echo $?
0
[root@localhost centos]# [ -d /etc/hosts ]
[root@localhost centos]# echo $?
1
[root@localhost centos]# [ -r /etc/hosts ]
[root@localhost centos]# echo $?
0
5、控制字符
; && ||
.
; 前后命令的执行没有相关性
&& 前面的成功才会执行后面的语句
|| 前面的成功执行,不执行后面。前面的执行失败,执行后面命令
实例:
[root@localhost home]# [ a == b ] && ls
[root@localhost home]# [ a == a ] && ls
centos l
[root@localhost home]# [ a == a ] || echo message
[root@localhost home]# [ a == b ] || echo message
message
[root@localhost home]# [ a == b ] && echo Y || echo N
N
[root@localhost home]# [ a == a ] && echo Y || echo N
Y
[root@localhost home]# [ $USER == root ] && echo Y || echo N
N
注意:a和==之间以及b和== 之间必需有空格
6、使用&&、|| 进行多个条件判断
[root@localhost home]# [ a == a ] && [ 3 -gt 4 ]
[root@localhost home]# echo $?
1
7、去除多余重复的字符串
[root@localhost shell]# echo "a b c" | tr -s " "
#删除多余的空格
[root@localhost shell]# echo "AAAAAAdadf " | tr -s "A"
Adadf
a b c
#删除多余的a
cut过滤数据
cut -d: -f1 /etc/passwd
实例1:使用脚本获取各项性能指标,并于阈值进行比较
local_time:时间
local_ip:ens32 网卡
ip free_mem:剩余内存大小
free_disk:剩余磁盘大小
cpu_load:15min 平均负载
login_user:登录系统的用户
proces:当前进程数据
local_time=$(date +"%Y-%m-%d %H:%M:%S")
local_ip=$(ifconfig ens32 | grep netmask | tr -s " " | cut -d " " -f3)
free_mem=$(cat /proc/meminfo | grep Avai | tr -s " " | cut -d "" -f3)
free_disk=$(df | grep "/$" | tr -s " " | cut -d "" -f4)
cpu_load=$(cat /proc/loadavg | cut -d "" -f3)
login_user=$(who | wc -l)
proces=$(ps aux | wc -l)
#当剩余内存不足1GB时发送有邮件给root进行报警
[ $free_mem -lt 1048 ] && echo "$local_time Freee memory not enough Free_mem : $free_mem on $local_ip" | mail -s Warning root@localhost
#当剩余磁盘不足10GB时发送邮件给root进行报警
[ $free_disk -lt 1048 ] && echo "$local_time Freee disk not enough " | mail -s Warning root@localhost
#CPU的15min平均负载超过4时发送邮件给root进行报警
result=$(echo "$cpu_load >4" | bc)
[ $result -eq 1 ] && echo "$local_time CPU load to high CPU 15 averageload: $cpu_load on $local_ip " | mail -s Warning root@localhost
#当系统实时在线人数超过3时发送邮件给root进行报警
[ $login_user -gt 3 ] && echo "$local_time Too many user $login_user users l ogin to $local_ip " | mail -s Warning root@localhost
#当实时进程数据大于500时发送邮件给root进行报警
[ $proces -gt 500 ] && echo "$local_time Too many procs $procs proc are runing on$local_ip" | mail -s Warning root@localhost
知识点
mail发送邮件1
mail发送邮件2
cut命令
tr命令
系统负载均衡:/proc/loadavg
shell流程控制
条件判断
当条件成立时执行命令序列
条件判断方式1
语法格式:
if 条件测试
then 命令序列
fi
if 条件测试; then
命令序列
fi
fi 条件测试
then
命令序列1
else
命令序列2
if
实例1:测试主机是否可以ping通
#-c(设置ping的次数),-i(设置ping的时间间隔),-W(设置超时时间)
ping -c2 -i0.1 -W1 "$1"
if [ $? -eq 0 ];then
echo -e "\033[34m $1 is up \033[0m"
else
echo -e "\033[34m $1 is down \033[0m"
fi
条件判断方式2
语法格式
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
实例1:判断数值是否想等
a=10
b=20
if [ $a == $b ]
then
echo "a 等于 b"
elif [ $a -gt $b ]
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "没有符合的条件"
fi
实例2:判断用户名和密码是否为空
read -p " your name:" user
read -s -p "your passwd" pass
if [ ! -z "$user" ]; then
useradd "$user"
fi
if [ ! -z "$pass" ]; then
echo "$pass"| passwd --stdin "$user"
fi
echo
优化代码
read -p " your name:" user
read -s -p "your passwd" pass
if [ ! -z "$user" ] && [ ! -z "$pass" ]; then
useradd "$user"
echo "$pass" | passwd --stdin "$user"
fi
实例3:猜数值大小
clear
num=$[RANDOM%10+1]
read -p "please num for 1-10: " guess
if [ $guess -eq $num ]; then
echo "you are right,this is :$num"
elif [ $guess -lt $num ];then
echo "you are error, this is little"
else
echo "your are error,this is great"
fi
for 循环
语法格式
for 变量 in item1 item2 ... itemN
do
command1
command2
...
commandN
done
for (( 初值;条件; 步长))
do
命令序列
done
实例1:循环输出数值
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
#将1,2,3,4,5分别赋值给loop这个变量
输出结果:
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5
实例2:
for(( i=1 ; i<=5 ; i++))
do
echo "I am $i"
done
结果
I am 1
I am 2
I am 3
I am 4
I am 5
实例3:批量添加用户名
for i in {1..10}
do
useradd test$i
echo "123456" | passwd --stdin test$i
done
实例4:读取账号列表问文件创建系统账户
[root@root shell]# ls
day1 user.txt
for i in $(cat user.txt )
do
useradd "$i"
echo "123456" | passwd --stdin "$i"
done
实例5:打印乘法表
for (( i=1;i<=9;i++))
do
for((j=1;j<=i;j++))
do
echo -n "$i*$j=$[i*j]"
done
echo
done
while语句
语法格式
while condition
do
command
done
实例1:
#!/bin/bash
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
运行脚本,输出:
1
2
3
4
5
死循环脚本:
while :
do
echo hello world
done
实例3:批量添加用户
PREFIX="tuser" ;i=1
while [ $i -le 5 ]
do
useradd ${PREFIX}$i
echo "123456" | passwd --stdin ${PREFIX}$i &> /dev/null
let i++ //递增控制,避免死循环
done
实例4:监控网络流量
while :
do
clear
echo "local ens32 information"
ifconfig ens32 | grep "RX pack" | tr -s "" | cut -d "" -f6
ifconfig ens32 | grep "TX pack" | tr -s "" | cut -d "" -f6
sleep 1
done
RX代表进站流量 TX代表出栈流量
case
语法格式:
检查、判断变量的取值
效果类似于多分支的if语句
如果于预设的值匹配,则执行对应的操作
命令序列最后必须以双分号结尾
实例1:判断linux系统版本
read -p " input redhat | fedora:" key
case $key in
redhat)
echo "fedora";;
fedora)
echo "redhat";;
*)
echo "please input redhat or fedora"
esac
实例2:判断输入
read -p " Are you sure ?[y/n]:" sure
case $sure in
y|Y|yes|YES)
echo "you enter $sure,OK";;
n|N|NO|no)
echo "you enter $suer,OVER";;
*)
echo "error";;
esac
实例3:石头剪刀布
game=(stone scissor cloth)
num=$[RANDOM%3]
computer=${game[$num]}
echo "please your num"
echo "1.stone"
echo "2.scissor"
echo "3.clothe"
read -p "please your choose 1-3:" person
case $person in
1)
if [ $num -eq 0 ];then
echo "draw"
elif [$num -eq 1 ];then
echo"you win"
else
echo"computer win"
fi;;
2)
if [$num -eq 0]; then
echo "computer win"
elif [$num -eq 1]; then
echo "draw"
else
echo "you win"
fi;;
3)
if [$num -eq 0]; then
echo "you win"
elif [$num -eq 1]; then
echo "computer win"
else
echo "draw"
fi;;
esac
中断与退出
continue:结束本次循环
for i in {1..5}
do
[ $i -eq 3 ] && continue
echo $i
done
[root@root shell]# bash day2
1
2
4
5
break:结束全部循环
for i in {1..5}
do
[ $i -eq 3 ] && break
echo $i
done
[root@root shell]# bash day2
1
2
exit退出当前脚本
for i in {1..5}
do
[ $i -eq 3 ] && exit
echo $i
done
实例1:前五个球为蓝色最后一个为红色
red_ball=""
blue_ball=""
while :
do
clear
echo "----choose your ball-----"
tmp=$[RANDOM%33+1]
echo "red_ball" | grep -q -w $tmp && continue
red_ball+=" $tmp"
echo -en "\033[91m $red_ball \033[0m"
word=$( echo "$red_ball" | wc -w )
if [ $word -eq 6 ]; then
blue_ball=$[RANDOM%16+1]
echo -e "\033[34m $blue_ball \033[0m"
break
fi
sleep 0.5
done
#echo "red_ball" | grep -q -w $tmp && continue
-q 为无论是否找到要找的字母都不返回结果显示在屏幕上,找的到$?返回结果0
-w 想确定某一个单词是啥,如abc 找a找不到。a bc 可以找到a
red_ball+=" $tmp" red_ball=$reb_ball+" $tmp"
这里的+为连接字符
函数
在Shell环境中,将一些需要重复使用的操作,定义为公共的语句块,即可称为函数。
shell中函数的定义格式如下:
function 函数名{
命令序列
}
函数名(){
命令序列
}
说明:
1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
实例1:
demoFun(){
echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"
输出结果:
-----函数开始执行-----
这是我的第一个 shell 函数!
-----函数执行完毕-----
实例2:
function demoFun {
echo "这是我的第一个 shell 函数!"
}
demoFun
输出结果:
这是我的第一个 shell 函数!
实例3:下面定义一个带有return语句的函数:
#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo "两个数字分别为 $aNum 和 $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
这个函数会对输入的两个数字进行相加运算…
输入第一个数字:
1
输入第二个数字:
2
两个数字分别为 1 和 2 !
输入的两个数字之和为 3 !
函数返回值在调用该函数后通过 $? 来获得。
注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
实例4:端口探测
myping (){
ping -c3 -i0.2 -W1 $1 &> /dev/null
if [$? -eq 0];then
echo " $1 is up"
else
echo " $1 is donw"
fi
}
for i in {1..254}
do
myping 192.168.1.$i &
done
wait
&:将执行的函数放入到后台执行,wait等待所有的后台进程结束退出脚本。
函数参数
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…
带参数的函数示例:
#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
输出结果:
第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !
注意,$10
不能获取第十个参数,获取第十个参数需要${10}
。当n>=10时,需要使用${n}
来获取参数。
综合案例
实例1、copy显示颜色
#!/bin/bash
bar(){
while :
do
echo -en "\033[44m \033[0m"
sleep 0.5
done
}
bar &
cp -r $1 $2
kill $! # $!最后一个在后台执行的 后台的进程号
echo
检查方式
Sleep 1 &
Echo $!
Sleep 20 $
Echo $!
实例2、查看系统资源
#!/bin/bash
clear
echo -e "\033[42m--------------\033[0m"
echo -e "#\e[32m 1.network card message \e[0m #"
echo -e "#\e[33m 2.memory message \e[0m #"
echo -e "#\e[34m 3.disk message \e[0m #"
echo -e "#\e[35m 4.CPU message \e[0m #"
echo -e "#\e[36m 5.user message \e[0m #"
echo -e "#\033[42m ----------------- \033[0m"
echo
read -p "please your number[1-5]:" key
case $key in
1)
ifconfig | head -2;;
2)
mem=$(free | grep Mem | tr -s "" | cut -d "" -f7)
echo "The remaining memory capacity is ${mem}K.";;
3)
root_free=$(df | grep /$ | tr -s "" | cut -d "" -f4)
echo "The remaining capacity of the partition is: ${root_free}.";;
4) cpu=$(uptime | tr -s "" | cut -d "" -f11)
echo "CPU load for 15 minutes: $cpu.";;
5)
login_number=$(who | wc -l)
total_number=$(cat /etc/passwd | wc -l)
echo "Current System User:$USER"
echo "The number of login accounts in the system is $total_number"
echo "The number of accounts in the system is $total_number.";;
*)
echo "input is erroring. Not in 1 to 5";;
esac
实例3、无线循环,消耗系统资源
#! /bin/bash
.(){ #定义函数,函数名为.
.|. & #在函数内调用自己
}
. #执行函数