Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?

文章目录

    • shell 编程
  • 一、变量
    • 1. shell脚本基础知识
    • 2.shell 编程的基本过程
    • 3. shell变量
  • 二、shell 功能语句
    • 常用功能性语句(命令)
    • 测试语句
  • 三、shell 分支语句
    • 1. 条件语句
    • 2. 多路分支语句
  • 四、shell 循环语句
    • 1. 循环语句for的用法
    • 2. 循环语句while的用法
    • 3. 循环控制语句
  • 五、shell 函数
    • 1. shell函数调用
    • 2. 函数变量作用域

shell 编程

一、变量

1. shell脚本基础知识

编译型语言:如 c语言
解释型语言:shell 脚本

shell脚本的本质:shell命令的有序集合

2.shell 编程的基本过程

基本过程分为三步:

  1. 建立shell文件:包含任意多行操作系统命令或shell命令的文本文件。——xx.sh
  2. 赋予shell文件执行权限chmod命令修改权限
  3. 执行shell文件,直接在命令行上调用shell程序

示例:

  1. 建立shell文件 prog1.sh
data
  1. 赋予shell文件执行权限 (初始文本文件无执行权限)
chmod 740 prog1.sh
#或者
chmod u+x prog1.sh
  1. 执行shell文件
prog1.sh
#结果为
prog1.sh :not found

原因是:shell在标准搜索路径中找不到prog1.sh
4.正确的执行shell文件

./prog1.sh
#结果为
20091216日 星期二 145257 CST

3. shell变量

shell允许用户建立变量存储数据,但不支持数据类型(整型,字符,浮点型),将任何赋给变量的值都解释为一串字符
Variable = value

  • count = 1
  • echo $ count
  • DATE = data
  • echo $ DATE

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第1张图片

注意几点:

  1. 变量没有类型

  2. =号两边不能加空格

  3. 变量必须是大写

  4. 赋值的时候要用``框起来

Bourne shell有如下四种变量:

  • 用户自定义变量

    1. 在shell编程中通常使用全大写变量:COUNT=1
    2. 变量的调用,在变量前加$:echo $HOME
    3. Linux shell / bash 从右向左赋值:Y=y、X=$Y、echo $X 、y
    4. 使用unset命令删除变量的赋值:Z=hello、echo $Z、hello、unset Z、echo$Z
  • 位置变量及命令行参数

    1. $0 与键入的命令行一样,包含脚本文件名
    2. $1,$2…$9 分别包含第一个到第九个命令行参数。
    3. $# 包含命令行参数的个数
    4. $@ 包含所有命令行参数: $1,$2,…$9
    5. $? 包含前一个命令的退出状态
    6. $* 包含所有命令行参数:$1,$2,…$9
    7. $$ 包含正在执行进程的ID号

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第2张图片Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第3张图片

  • 预定义变量

在这里插入图片描述 在这里插入图片描述 Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第4张图片 Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第5张图片

在这里插入图片描述
必须在两位数边写上 { } ,才能正常值一一样。Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第6张图片

  • 环境变量
    1. HOME:/etc/passwd文件中列出的用户目录
    2. IFS: Internal Field Separator , 默认为空格,tab及换行符
    3. PATH:shell搜索路径
    4. PS1,PS2:默认提示符($)及换行提示符(>)
    5. TERM:终端类型,常用的有vt100,ansi,vt200,xterm等。

二、shell 功能语句

shell 程序由零或多条shell语句构成。shell语句包括三类:说明性语句,功能性语句和结构性语句。

**说明性语句 ** 以 # 号开始到该行结束,不被解释执行
功能性语句 任意的shell命令,用户程序或其他shell程序
结构性语句 条件测试语句,多路分支语句,循环语句,循环控制语句等。

#!/bin/sh
#
# 本程序说明
#
command_1
command_2     #command_2的语句说明
....

常用功能性语句(命令)

read 从标准输入读入一行,并赋值给后面的变量,其语法为:

read var

把读入的数据全部赋给var

read var1 var2 var3

把读入行中的第一个单词(word)赋给var1 ,第二个单词赋给var2,…把其余所有的词赋给最后一个变量。
如果执行read语句时标准输入无数据,则程序在此停留等候,直到数据的到来或被终止运行。

#!/bin/bash
echo "input a number:"
read NUM
echo $NUM

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第7张图片

#!/bin/bash
echo "input year month day:"
read Y M D
echo "Today is $Y-$M-$D"

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第8张图片
expr命令:
算术运算命令expr主要用于进行简单的整数运算,包括加(+)、减(-)、乘(*)和求模(%)等操作。例如

$expr 12 + 5 \* 3
27
$expr 3 - 8 / 2
-1
$num=9
$sum=`expr $num \* 6`
$echo $sum
54

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第9张图片
在这里插入图片描述

!!运算符间用空格分开!!

测试语句

test语句

test语句可测试三种对象:

字符串 / 整数 / 文件属性

每种测试对象都有若干测试操作符
例如:

test "$answer" = "yes"
#变量answer的值是否为字符串yes

test $num -eq 18
#变量num的值是否为整数18

test -d tmp
#测试tmp 是否为一个目录名

字符串测试:

s1 = s2 测试两个字符串的内容是否完全一样
s1 != s2 测试两个字符串的内容是否有差异
-z s1 测试s1 字符串的长度是否为0
-n s1 测试s1 字符串的长度是否不为0

整数测试:

a - eq b 测试a 与 b是否相等
a - ne b 测试a 与 b是否不相等
a - gt b 测试a 是否大于b
a - ge b 测试a 是否大于相等b
a - lt b 测试a 是否小于b
a - le b 测试a 是否小于等于b
#!/bin/bash

A="how"
B="hoW"
test $A = $B
echo $?   //表示输出前一个语句的结果

在这里插入图片描述

#!/bin/bash

A="how"
B="how"
test $A = $B
echo $?   //表示输出前一个语句的结果

在这里插入图片描述
相等为0(真),不等为1(假)

#!/bin/bash

A="how"
B="hoW"
test $A = $B
echo $?   //表示输出前一个语句的结果

pwd
echo $?

ls file
echo $?

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第10张图片
最后ls file 没有,所以结果为2

#!/bin/bash

A=99
B=88
test $A -ne  $B
echo $?   //表示输出前一个语句的结果

test $A -gt  $B
echo $?   //表示输出前一个语句的结果

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第11张图片

三、shell 分支语句

1. 条件语句

if …then…fi
语法结构:

if   表达式
              then  命令表
fi   
  • 如果表达式为真,则执行命令表种的命令;否则退出if语句,即执行fi后面的语句
  • if和fi是条件语句的语句括号,必须成对使用;
  • 命令表中的命令可以是一条,也可以是若干条。
#!/bin/bash

if [ $# -ne 1 ]
then   
       echo "usage : $0 filename"
       exit
fi
if ! [ -e  $1 ]
then 
        echo " $1 not exist"
        exit
fi 
if [ -d $1 ]
then
         echo "$1 is a dirextory"
fi

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第12张图片
if…then …else…fi
语句结构为:

if    表达式
then   命令表1
else    命令表2
fi

如果表达式为真,则执行命令表1中的命令,在退出if语句;否则执行命令表2中的语句,在退出if语句。

注意:无论表达式是否为真,都有语句要执行

#!/bin/bash

if [ $# -ne 1 ]
then   
       echo "usage : $0 filename"
       exit
fi
if ! [ -e  $1 ]
then 
        echo " $1 not exist"
        exit
fi 
if [ -L $1 ]
then
         echo "l"
elif [ -d $1 ]
then
         echo "-"
elif [ -b $1 ]
then 
         echo "b"
else
         echo "csp"
fi

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第13张图片

2. 多路分支语句

case…esac
多路分支语句case用于多重条件测试,语法结构清晰自然,

case  字符串变量   in   //case语句只能检测字符串变量
      模式1)
               命令表1  //各模拟中可用文件名元字符,以右括号结束
               ;;
      模式2 | 模式3)
               命令表2
               ;;    //命令表以单独的双分号行结束,退出case语句
.....
模式n)
                命令表n
                ;;     //模式n常写为字符*,表示所有其他模式
esac                    //最后一个双分号行可以省略

判断选择——多路分支语句 示例1:

#!/bin/bash

echo -n "please choose (yes | no)?"
read R
case $R in
        yes | Yes |y | Y |YES )
             echo  "yes"
             ;; 
         no)
             echo  "no"
             ;;
         *)
             echo   "wrong"
             #;;
esac

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第14张图片
判断成绩——多路分支语句 示例2:

#!/bin/bash

echo -n "please choose (yes | no)?"
read S
if [ $S -lt 0 -o $S -gt 100]
then 
        echo "no in [0-100]"
        exit      
fi

G=`expr $S / 10`
case $G in
        9|10)
             echo  "$S A"
             ;; 
         6|7|8)
             echo  "$S B"
             ;;
         *)
             echo   "$S C"
             #;;
esac

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第15张图片

四、shell 循环语句

1. 循环语句for的用法

当循环次数已经知道或确定时候,使用for循环语句来多次执行一条或者一组命令,循环体由语句括号do和done来限定。

格式为:

for    变量名    in   单词表
         do  
                     命令表
          done

变量依次取单词表中的各个单词,每取一次单词,就执行一次循环体中的命令。循环次数由单词数确定。命令表中的命令可以是一条,也可以是由分号或换行符分开的多条。
如果单词表是命令行上的所有位置参数时,可以在for

实例代码:

#!/bin/bash

#for I  in `ls /etc`
do  
       echo "$I"
done

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第16张图片

seq命令 :列出一系列的数字
seq 起始数字 中间分量 终止分量

#!/bin/bash
for I in `seq 1 2 10`
do
      echo "$I"
done

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第17张图片
示例:拷贝当前目录下的所有文件到backup子目录下。
使用语法为:./prog5.sh[filename]

#The statement of for ....do...done
if [! -d $HOME/backup ]
then
        mkdir $HOME/backup
fi
flist=`ls`
for file in $flist   //flist的值是ls的执行结果即当前目录下的文件名
do
     if [ $# = 1 ]
     then
             if [ $1 = $file ]   //命令行上有一个参数时
             then
                        echo "$file found" ;  exit
             fi
      else 
             cp $file $HOME/backup
             echo "$file copied"   
      fi
done
echo  ***Backup Completed******           

2. 循环语句while的用法

语法结构:

while    命令或表达式
          do
               命令表
          done

while语句首先测试其后的命令或表达式的值,如果为真,就执行一次循环体中的命令,然后再测试该命令或表达式的值,执行循环体,直到该命令或表达式为假时退出循环。

示例:

#!/bin/bash

I=0

while [ $I -lt 5 ]   //-lt  =  <
do
      I=`expr $I + 1`
      echo -n "input score:"
      read $S

      case `expr $S / 10` in
         9|10)
              echo "A"
              ;;
        6|7|8)
              echo "B"
              ;;
        *)
              echo "C"
              ;;
    esac
    echo "$I"
done

3. 循环控制语句

break 和 continue

break n 则跳出n层;
continue语句则马上转到最近的一层循环语句的下一轮循环上,
continue n 则转到最近n层循环语句的下一轮循环上。

用法:prog7 整数 整数 整数 …
参数个数不确定,范围为1-10个 ,每个参数都是正整数。

示例:

#!/bin/bash

if [ $# -ne 5 ]
then 
      echo "argument 5"
      exit
fi

for I
do
    if [ `expr $I % 2` -eq 1 ]
    then
         echo "$I"
         else
                break
    fi
done        

若是break 的话 ,跳出整个循环。遇到偶数就跳出循环。
在这里插入图片描述

#!/bin/bash

if [ $# -ne 5 ]
then 
      echo "argument 5"
      exit
fi

for I
do
    if [ `expr $I % 2` -eq 1 ]
    then
         echo "$I"
         else
                continue
    fi
done        

若是continue的话 ,跳出当前循环。遇到偶数就跳出当前循环,继续执行下面语句
在这里插入图片描述

五、shell 函数

1. shell函数调用

函数调用格式:

方式1:
value_name=`function_name  [arg1 arg2 ...]`

函数的所有标准输出都传递给了主程序的变量

方式2:
function_name [arg1 arg2 ...]
echo $?

获取函数的返回状态

获取函数的返回状态 ——示例:

grep_user()
{
   R=`grep "$1" /etc/passwd | wc -l`
   echo $R
   return $R
}

echo -n "input username:"
read USER
grep_user $USER
RET=$?
if [ $USER -eq 1 ]
then   
       echo "$USER exist"
else
       echo "$USER not exist"
fi

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第18张图片
若改为不返回值,用变量,函数的所有标准输出都传递给了主程序的变量

grep_user()
{
   R=`grep "$1" /etc/passwd | wc -l`
   echo $R
}

echo -n "input username:"
read USER
RET=`grep_user $USER`
echo "----return $RET-----"
if [ $USER -eq 1 ]
then   
       echo "$USER exist"
else
       echo "$USER not exist"
fi

Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第19张图片

2. 函数变量作用域

  • 全局作用域:在脚本的其他任何地方都能够访问该变量
  • 局部作用域:只能在声明变量的作用域内访问
  • 声明局部变量的格式:
    • c Local variable_name = value
grep_user()
{
      B=200
      A=100
}

grep_user
echo "end: $A-$B"

结果发现函数内的变量,竟然是全局变量
Linux基础——”shell脚本编程“ 你知道自动轰炸脚本怎么来的吗?_第20张图片

如果我们要局部变量就 加一个local

grep_user()
{
      B=200
      local A=100
}

grep_user
echo "end: $A-$B"

在这里插入图片描述

你可能感兴趣的:(Linux,开发,linux,ubuntu)