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

相关推荐

  • 基于ansible role实现LAMP平台批量部署

    前言 作为运维人员,当面对几十台或上百台服务器需要修改某个参数或部署某个平台,你将从何入手呢?ansible的出现很好的解决了这一困扰,ansible基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。本文带来的是基于Ansible Role…

    Linux干货 2015-06-11
  • iptables

    iptables 一、基础概念 1、防火墙概念 Firewall:隔离工具;Packets Filter Firewall;工作于主机或网络的边缘,对经由的报文根据预先定义的规则(匹配条件)进行检测,对于能够被规则匹配到的报文实行某预定义的处理机制的一套组件; 如果没有防火墙,你的本机的所有端口都会被别人访问到! 2、分类 硬件防火墙:在硬件级别实现部分功能…

    2016-10-26
  • systemd和systemctl

    systemd和systemctl(centos7)     Systemd是一种新的linux系统服务管理器。它替换了init系统,能够管理系统启动过程和一些系统服务,一旦启动起来,就将监管整个系统。在centos7系统中,PID 1被systemd所使用了:如下,在centos6中: init─┬─NetworkManager &nb…

    Linux干货 2016-10-09
  • Linux源程序包管理器之RPM

    一、 RPM功能描述 l  打包 l  安装 l  卸载 l  升级 l  校验 l  数据库管理 二、 RPM包命名格式 1.       命名格式举例 name-version-relase.arch.rpm 例如:bash-4.2.3…

    系统运维 2015-09-25
  • 关于大型网站技术演进的思考(七):存储的瓶颈(7)

    原文出处: 夏天的森林  本文开篇提个问题给大家,关系数据库的瓶颈有哪些?我想有些朋友看到这个问题肯定会说出自己平时开发中碰到了一个跟数据库有关的什么什么问题,然后如何解决的等等,这样的答案没问题,但是却没有代表性,如果出现了一个新的存储瓶颈问题,你在那个场景的处理经验可以套用在这个新问题上吗?这个真的很难说。 其实不管什么样的问题场景最…

    2015-03-11
  • 第九周脚本练习

    1、写一个脚本,判断当前系统上所有用户的shell是否为可登录shell(即用户的shell不是/sbin/nologin);分别这两类用户的个数;通过字符串比较来实现; awk -F: ‘{if($NF!=”/sbin/nologin”) print $1}’ /etc/passwd | wc -l 2、写一个脚本 (1) 获取当前主机的主机名,保存于ho…

    Linux干货 2017-03-30