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

相关推荐

  • 关于大型网站技术演进的思考(十五)–网站静态化处理—前后端分离—中(7)

    原文出处: 夏天的森林    上篇里我讲到了一种前后端分离方案,这套方案放到服务端开发人员面前比放在web前端开发人员面前或许得到的掌声会更多,我想很多资深前端工程师看到这样的技术方案可能会有种说不出来的矛盾心情,当我的工作逐渐走向越来越专业化的前端开发后,我就时常被这套前后端分离方案所困惑,最近我终于明白了这个困惑的本源在哪里…

    Linux干货 2015-03-11
  • Linux基础与命令解释

    Linux基础与命令 Linux起源      1984 年:Richard Stallman 发起GNU 项目和自由软件基金会 创建开源的UNIX 实用工具版本 创建通用公共许可证(GPL) ) 开源软件许可实施原则  1991 年:Linus Torvalds 发布Linux 创建开放源码,类Unix 的内核,在GPL 下发布 下…

    Linux干货 2017-03-17
  • 逻辑卷管理

    逻辑卷管理 一 创建逻辑卷 1 准备分区或硬盘 这里使用/dev/sdb、/dev/sdc两块硬盘和/dev/sda9、/dev/sda10两个分区,大小都为1G,磁盘有限,我也不想这么抠的。 添加分区/dev/sda9、 /dev/sda10 [root@centos7 ~]# fdisk /dev/sda Welcome to fdisk (u…

    Linux干货 2017-05-02
  • ​文本编辑器nano

    新建/打开文件     nano 路径+文件名,文件存在则为打开,否则新建;(未输入文件名,编辑完成后,保存退出会提示输入文件名); nano     note:nano中,黑底白字表示快捷键操作。其中“^”表示Ctrl键,则Ctrl+G就表示成“^G”。“M”表示 Alt键,则Alt+W表示为“M…

    Linux干货 2016-05-05
  • 互联网安全之iptables/netfilter入门到进阶

    随着互联网技术的方兴未艾,各种网络应用层出不穷,网络攻击、黑客入侵也成了网民畅游互联网的心头大患,互联网安全也愈加受到了人们的重视。网络防火墙,作为一种简单高效的互联网防御手段,逐渐成为了网民畅游网络世界的保护伞。下面笔者介绍下Linux系统的守卫者——iptables/netfilter。  一 兄弟齐心,其利断金  iptables/netfilter就…

    Linux干货 2017-05-06
  • 防护墙服务

    iptables的基本认识        Netfilter组件: 内核空间,集成在linux内核中 扩展各种网络服务的结构化底层框架 内核中选取五个位置放了五个Hook(勾子)function(INPUT、OUTPUT、FORWARD、PREROUTING、POST ROUTING),而这五个hoot functio…

    2017-08-21