Linux-Shell 编程

第二阶段、shell编程(1)

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 查看是否修改成功

预定义变量

用来保存脚本程序的执行信息

  1. 直接使用这些变量
  2. 不能直接变量赋值

变量名

$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

/dev/null目录理解

实例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
.(){         #定义函数,函数名为.
.|. &        #在函数内调用自己
} 
.            #执行函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值