shell脚本编写-4

1、while 循环的特殊用法(遍历文件的每一行)

while read line; do

循环体

done < /PATH/FROM/SOMEFILE

依次读取/PATH/FROM/SOMEFILE 文件中的每一行,且将行赋值给变量line

练习:扫描/etc/passwd 文件每一行,如发现GECOS 字段为空,则填充用户名和单位电话为62985600 ,并提示该用户的GECOS信息修改成功。

#!/bin/bash

while read mline;do

  if [ -z "`echo $mline|cut -d: -f5`" ];then

     username=`echo $mline|cut -d: -f1`

     chfn -f "$username" $username &>/dev/dull

     chfn -p "62895000" $username &>/dev/dull

     echo "finger is changed successfully"

  fi    

done</etc/passwd

或#while read -p “please input the number:”num;do echo the number is $num;done而且这也是个死循环

或# sum=0;while read line;do sum=$[sum+`echo $line|cut -d: -f3`];done</etc/passwd;echo $sum

2、双小括号方法,即((…)) 格式,也可以用于算术运算

 双小括号方法也可以使bash Shell实现C语言风格的变量操作

例如:

#i=10

#((i++))

 for循环的特殊格式:

for (( 控制变量初始化; 条件判断表达式; 控制变量的修正表达式));do

循环体

done

控制变量初始化:仅在运行到循环代码段时执行一次

控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断

例如:# sum=0;for i in {1..100};do sum=$[sum+i];done;echo $sum

      #sum=0;for ((i=1;i<=100;i++)) ;do sum=$[sum+i];done;echo $sum

      # for ((sum=0,i=1;i<=100;i++)) ;do sum=$[sum+i];done;echo $sum

1、 select循环与菜单

select variable in list

do

循环体命令

done

select循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准输出上,并显示PS3提示符,等待用户输入,用户输入菜单列表中的某个数字,执行相应的命令,同时用户输入的数字被保存在内置变量 REPLY中

select是个无限循环,因此要记住用 break命令退出循环,或用 exit命令终止脚本。也可以按 ctrl+c退出循

select经常和 case联合使用

与for 循环类似,可以省略 in list ,此时使用位置参量,例#select.sh gb yz hos

例如:

#!/bin/bash

select caidan in gb yz hos;do

   case $caidan in

   gb)

     echo 10$

     echo $REPLY

     break

     ;;

   yz)

     echo 20$

     break

;;

   hos)

     echo 30$

     break

;;

   *)

     echo noexist

     break

;;

   esac

done

运行此脚本,其PS3提示符是#?,不过可以定义,例如在脚本中假如代码PS3=“what do you want?”

2、 函数(shell命令,shell程序,shell可以是一个终端shell、也可以是一个脚本shell)

函数function 是由若干条shell命令组成的语句块,实现代码重用和模块化编程;它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分。

函数和shell程序比较相似,区别在于:

Shell程序在子Shell中运行,而Shell函数在当前Shell中运行,是shell程序的一部分,因此在当前Shell中,函数可以对shell中变量进行修改

函数由两部分组成:函数名和函数体

  语法一:

function f_name {

… 函数体…

}

  语法二:

f_name() {

… 函数体…

}

定义函数f2 () {

a=xixi

}

#!/bin/bash

a=haha

f2

echo $a

脚本的运行结果是输出xixi

5、函数的定义和使用:

可在交互式环境下定义函数

示例:

$dir() {

> ls -l

> }

定义该函数后,若在$后面键入dir ,即$dir其显示结果同ls -l的作用相同

该dir函数将一直保留到用户从系统退出,或执行了所示的unset 命令即$unset dir

可将函数放在脚本文件中作为它的一部分

可放在只包含函数的单独文件中

调用:函数只有被调用才会执行

调用:给定函数名,函数名出现的地方,会被自动替换为函数代码

函数的生命周期:被调用时创建,返回时终止

示例:

[root@centos7 bin]# vim functionadd-reduce.sh

#!/bin/bash

add () {

  echo $[$1+$2]

}

reduce () {

  echo $[$1-$2]

}

add $1 $2

reduce $1 $2

此外,函数在使用前必须定义,因此应将函数定义放在脚本开始部分,直至shell首次发现它后才能使用,调用函数仅使用其函数名即可

3、 使用函数文件

可以将经常使用的函数存入函数文件,然后将函数文件载入shell。

文件名可任意选取,但最好与相关任务有某种联系,例如:functions.main

一旦函数文件载入shell ,就可以在命令行或脚本中调用函数

可以使用set 命令显示查看所有已经载入shell 中的函数

若要改动函数,首先用unset 命令从shell中删除函数,改动完毕后,再重新载入此文件

 函数文件已创建好后,要将它载入shell

定位函数文件并载入shell 的格式:

. filename 或 source filename

     注意:此即< 点> < 空格> < 文件名>

这里的文件名要带正确路径(绝对或者相对路径)

示例:上例中的函数调用,可使用如下命令:

在终端shell中调用函数,如$ . functions.main

或者脚本中调用,例如在脚本中写入 . /root/funs代码,其中/root/funs是绝对路径函数文件,然后就可以使用其中的函数

函数可以接受参数:调用函数时,在函数名后面以空白分隔给定参数列表即可

例如“testfunc arg1 arg2 …”

在函数体中当中,可使用$1, $2, … 调用这些参数;还可以使用$@, $*, $# 等特殊变量

#!/bin/bash

. /root/funs

add $1 $2

reduce $1 $2

6、变量作用域:

环境变量:当前shell和子shell有效

本地变量:只在当前shell进程有效,本地变量的作用范围是当前shell脚本程序文件,包括脚本中的函数

局部变量:函数的生命周期,函数结束时变量被自动销毁

注意:如果函数中有局部变量,如果其名称同本地变量,则函数使用局部变量

 在函数中定义局部变量的方法

local NAME=VALUE

7、函数的退出状态码:

(1)  默认取决于函数中执行的最后一条命令的退出状态码

(2)  自定义退出状态码, 其格式为:

return 从函数中返回,用最后执行的命令状态决定返回值

return 0 无错误返回

return 1-255 有错误

在函数中遇见return就结束函数执行,此函数中return后面的代码不再执行

使用#echo $?可以查看函数的退出状态码

8、 函数递归实例

函数递归:函数直接或间接调用自身,注意递归层数

阶乘亦可以递归方式定义:0!=1 ,n!=(n-1)! ×n

n!=n(n-1)(n-2)…1

n(n-1)! = n(n-1)(n-2)!

示例:fact.sh

#!/bin/bash

fact() {

if [ $1 -eq 0 -o $1 -eq 1 ]; then

echo 1

else

echo $[$1*$(fact $[$1-1])] 注意其中的小括号

fi

}

fact 10

另外sumR.sh

#!/bin/bash

fact() {

if [ $1 -eq 1 ]; then

echo 1

else

echo $[$1+$(fact $[$1-1])]

fi

}

fact $1

 

练习题

1、 每隔3秒钟到系统上获取已经登录的用户的信息;如果发现用户hacker登录,则将登录时间和主机记录于日志/var/log/login.log中,并提示该用户退出系统
#!/bin/bash
while true;do
  who
  who|grep -q "^shanhaibo\>"
  if [ $? -eq 0 ];then
      who>>/var/log/login.log
      write shanhaibo <./hacker.txt
  fi
     sleep 3
done
2、随机生成10以内的数字,实现猜字游戏,提示比较大或小,相等则退出
#!/bin/bash
a=$[$RANDOM%11]
read -p "please input the positive integer 0-9:" b
[[ ! $b =~ [0-9] ]] && echo "this input isn't positive integer[0-9]" && exit
until [ $a -eq $b ] && echo "you are good";do
    if [ $b -gt $a ];then
       echo "the positive integer is bigger"
    else
       echo "the positive integer is less"
    fi
    read -p "please input the positive integer 0-9:" b
done
8、打印等腰三角形
第一种方法:
#!/bin/bash
read -p "please input the line:" n
for i in `seq 1 $n`;do
   for j in `seq 1 $[n-i]`;do
     echo -n " "
   done
   b=$[i*2-1]
   for h in `seq 1 $b`;do
   echo -n "#"
   done
echo
done
第二种方法:
#!/bin/bash
read -p "please input the line:" n
for i in `seq 1 $n`;do
   for j in `seq 1 $[n+i]`;do
       if [ $j -le $[n-i] ];then
           echo -n " "
       elif [ $j -lt $[n+i] ];then
           echo -n "#"
       fi
   done
echo
done


 

原创文章,作者:18612763863,如若转载,请注明出处:http://www.178linux.com/42378

(0)
1861276386318612763863
上一篇 2016-09-01
下一篇 2016-09-01

相关推荐

  • linux发展史

    linux发展史简介: 20世纪60年代,MIT开发分时操作系统(Compatible TIme-Sharing System),支持30台终端访问主机;     ~主机负责运算,而终端负责输入输出; 1965年,Bell实验室、MIT、GE(通用电气公司)准备开发Multics系统,为了同时支持3…

    Linux干货 2016-10-14
  • 逻辑卷的创建、维护和迁移

    逻辑卷管理器(LVM)介绍: 1、允许对卷进行方便操作的抽象层,包括重新设定文件系统的大小 2、允许在多个物理设备间重新组织文件系统 (1)将设备指定为物理卷 (2)用一个或者多个物理卷来创建一个卷组 (3)物理卷是用固定大小的物理区域(Physical Extent,PE)来 定义的 (4)在物理卷上创建的逻辑卷 是由物理区域(PE)组成 (5)可以在逻辑…

    Linux干货 2017-12-10
  • 推荐-虚拟化网络之OpenvSwitch(二)

    上一篇介绍了openvswitch的基础知识,接下来我们来做一个实验,利用GRE通道搭建一个跨多宿主机的虚拟化网络,深入了解openvswitch的功能。 一、实验拓扑 ip地址分配:  A1:192.168.10.1/24  A2:192.168.10.10/24   B1:192.168.10.2/24 &nbsp…

    2016-03-27
  • 小白易患错误之绝对路径和相对路径的操作错误

    小白易患错误之绝对路径和相对路径的操作错误 作为一个不安稳的小白,一天都在那路乱折腾,恰巧,老师课程题目中有一题将/etc/skel 这个目录的文件除了..和. 复制到/home/USRNAEM 的家目录下。然后自以为是不按照老师的方法,自己折腾用了这样一条命令 [root@local skel]# ls -A .bash_lo…

    Linux干货 2016-08-05
  • 马哥教育网络班20期+第2周课程练习

    1、Linux上的文件管理类命令都有哪些,其常用的使用方法及其相关示例演示。  文件管理类命令有ls,cat,touch,stat,cp,mv,rm等  ls:查看文件,其使用方法以及常用选项有: Usage: ls [OPTION]… [FILE]… 常用选项:   -a:列出所有内容,包括.和.. &…

    Linux干货 2016-06-23
  • 请使用命令行展开功能来完成以下练习

    (1)、创建/tmp目录下的:ac, ad, bc, bd ]# mkdir -p /tmp/{a,b}_{c,d} 或者: ]# touch /tmp/{a,b}_{c,d} (2)、创建/tmp/mylinux目录下的: ]# mkdir -pv /tmp/mylinux/{bin,boot/gtub,dev,etc/{rc.d/init.d,sysco…

    Linux干货 2016-11-06