Shell编程之算数、条件测试read详解二(待续...)

一、shell脚本编程
Shell和shell脚本的区别
    shell就是一个命令行解释器,它的作用就是遵循一定的语法将输入的命令加以解释并传给系统。它为用户提供了一个向Linux发送请求以便运行程序的接口系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。Shell本身是一个用C语言编写的程序,他是用户使用Linux的桥梁。

        shell即是一种命令语言,优势一种程序设计语言(就是我们所说的shell脚本)。作为命令语言,它互动德解释和执行用户输入的命令;作为程序命令语言它定义了各种变量和参数,并提供了许多在高阶语言中才具有的控制结构,包括循环和分支。


  (1)bash中的算术运算

        操作符:+, -, *, /, %(取余),

            +=, -=,*=, /=, %=

       declare

            -i:整型变量

            -x:环境变量,类似于export

        let varName='算数表达式'

        varName=$[算术表达式]

        varName=$((算术表达式))

        varName=`expr $num1 + $num2`

示例:

(1)

# num1=5
# num2=6
# let sum="$num1*$num2"
# echo $sum
30

# sum=$[num2 - num1]
# echo $sum
1

# sum=`expr $num1 + $num2`
# echo $sum
11

# num1=11
# num2=5
# sum=$((num1/num2))
# echo $sum
2
注意:如果计算结果中存在小数,将会被圆整;

# num1=11
# num2=2
# sum=$[num1%num2]
# echo $sum
1

#a=40
#a=$[a+=2]
#echo $a
42 
自加并赋值给自身

# a=$[a-=2]
# echo $a
40
自减并赋值给自身

#a=40
# a=$[a*=2]
# echo $a
80
乘等并赋值给自身
.....

(2)计算100以内所有整数之和;
#!/bin/bash
#
declare -i sum=0
for i in {1..100}; do
    let sum=$[$sum+$i]
done
echo "The sum is: $sum."

(3)分别计算100以内所有偶数之和和奇数之和;
#!/bin/bash
#
declare -i oddSum=0, evenSum=0
for i in `seq 1 2 100`; do
    oddSum=$[$oddSum+$i]
done

for j in `seq 2 2 100`; do
    evenSum=$[$evenSum+$j]
done
echo "The even Sum is: $evenSum, the odd sum is: $oddSum"



(2)变量的类型

    本地变量:只对当前shell进程有效,对其子shell及其他shell都无效;

        定义变量:[set]Var_Name="Value"

        引用变量:${Var_Name}

        撤销变量:unset Var_Name

    局部变量:仅对局部代码生效;

        local Var_Name="Value"

    环境变量:对当前shell进程及其子进程有效;

        export Var_Name="Value"

    位置参数变量:

        $0:脚本自身

(4)#!/bin/bash
#
echo "The sum is: $[$1+$2]"
echo $0
# ./opt.sh 10 11 
The sum is: 21
./opt.sh


        $1:脚本的第一个参数

        $2:脚本的第二个参数

         ....

(5)     

#!/bin/bash
#
echo "The sum is: $[$1+$2]"

#chmod +x opt.sh
#./opt.sh 10 11
The sum is: 21


    特殊变量

             $#:位置参数的个数;

# ./opt.sh 10 11 9 8
The sum is: 21
4


         $*,$@:引用所有的位置参数

(6)

#!/bin/bash
#
echo "The sum is: $[$1+$2]"
echo $*
echo $@
# ./opt.sh 10 11 9 8
The sum is: 21
10 11 9 8
10 11 9 8

         $?:上一条命令的执行状态

            状态用数字表示:

            0:表示成功

            1-255:失败

   

        给变量以默认值

            varName=${varName:-value}

            如果varName不空,则其值不变;否则,VarName会使用value做为其值;

Shell编程之算数、条件测试read详解二(待续...)_第1张图片

        read:用户交互脚本;

        -p:提示符

        -t [n]:超时时间

(7)

#!/bin/bash
#
read -t 5 -p "Enter a number: " num

num=${num:-0}
echo $num
# ./num1.sh 
Enter a number: 0     #上面-t指定的超时时间为5秒钟,如果执行脚本之后等5秒钟(或直接回车),就会把设定的默认值显示出来;

(8)通过键盘给定一个文件的路径,来判断文件内容的类型:
vim judge.sh
#!/bin/bash
#
read -p "Enter a file path: " fileName
file $fileName

bash judge.sh
Enter a file path: /etc/issue
/etc/issue: ASCII text


二、Bash编程之条件判断:

    条件判断的常用测试类型:

       整数测试

       字符测试

       文件测试

    命令状态返回值:

        $?

        0:真

        1-255:假

    逻辑运算:

    与运算:

      真 && 真 = 真

      真 && 假 = 假

      假 && 真 = 假

      假 && 假 = 假

    或运算:

       真 || 真 = 真

       真 || 假 = 真

       假 || 真 = 真

       假 || 假 = 假

    非运算:

       !真 = 假

       !假 = 真


Bash中条件判断中if的使用;

    单分支:

       if 条件;then

           分支1

       fi

    双分支:

       if 条件;then

           分支1

       else

           分支2

       fi

    多分支:

       if 条件1;then

           分支1;

       elif 条件2;then

           分支2;then

       elif 条件3;then

           分支3;

       .....

       else

           分支n;

       fi

示例:

(9)让用户指定一个文件,判定;如果文件有空白行,就显示空白行数,否则,就说明文件无空白行;

#!/bin/bash
#
read�p “Enter a file path: ” filename
if grep “^$”$fileName &> /dev/null; then
    linesCount=`grep “^$” $fileName | wc -l`
    echo “$fileName has $linesCount space lines.”
else
    echo “$fileName hava no space line.”
fi

(10)

显示如下菜单:

cpu)show cpu info;

mem)show memory info;

quit)quit

Enter your options: CPU Cpu Cpu

如果用户选择cpu,则显示文件/proc/cpuinfo的信息;

无果用户选择mem,则显示文件/proc/meminfo的信息;

如果用户选择quit,则退出,并且退出吗为5;

如果用户键入其他字符,则显示位置选项,请重新执行脚本;退出码为6;

vim showinfo.sh
#!/bin/bash
#
returnValue=0

cat << EOF
cpu) print cpu infomation
mem) print memory infomation
quit) Quit
EOF

read -p "Enter your option: " userOption
userOption=`echo $userOption | tr 'A-Z' 'a-z'`

if [[ "$userOption" == "cpu" ]]; then
    cat /proc/cpuinfo
elif [[ "$userOption" == "mem" ]]; then
    cat /proc/meminfo
elif [[ "$userOption" == "quit" ]]; then
    echo "quit"
    returnValue=6
else
    echo "unkown option"
    returnValue=7
fi

exit $returnValue



# bash showinfo.sh 
cpu) print cpu infomation
mem) print memory infomation
quit) Quit
Enter your option: Cpu
processor    : 0
vendor_id    : GenuineIntel
cpu family    : 6
model        : 61
model name    : Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz
stepping    : 4
microcode    : 0x12
cpu MHz        : 2194.940
cache size    : 3072 KB
physical id    : 0
......
## bash showinfo.sh 
cpu) print cpu infomation
mem) print memory infomation
quit) Quit
Enter your option: mem
MemTotal:        1001364 kB
MemFree:          398512 kB
MemAvailable:     605652 kB
Buffers:            2164 kB
Cached:           204948 kB
SwapCached:            0 kB
Active:           162280 kB
Inactive:         102440 kB
Active(anon):      67388 kB
Inactive(anon):    15868 kB
Active(file):      94892 kB
Inactive(file):    86572 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       2098172 kB
SwapFree:        2098172 kB
Dirty:                 0 kB
.......

#bash showinfo.sh 
cpu) print cpu infomation
mem) print memory infomation
quit) Quit
Enter your option: quit
quit
# echo $?
6

# bash showinfo.sh 
cpu) print cpu infomation
mem) print memory infomation
quit) Quit
Enter your option: hello
unkown option
# echo $?
7


测试表达式:

    test 测试表达式

    [ 测试表达式 ]

    [[ 测试表达式 ]]

1、整数测试:

        -eq:是否等于

        -ne:是否不等

        -gt:大于

        -lt:小于

        -ge:大于等于

        -le:小于等于

(11)判定两个数谁大谁小,整数是通过命令行参数传递;

vim j.sh
#!/bin/bash
#
if [ $1 �gt $2 ]; then
    echo “The max num is $1.”
else
    echo “The max num is $2.”
fi
#bash j.sh 56 34
Themax num is 56
#Bash j.sh 56 134
The max nu is 134

(12)脚本自定义退出:exit [n]

vim hello.sh
#!/bin/bash
#
echo“hello world”
exit6
echo“hello”
#bash hello.sh
hello world
#echo $?
6

(13)判定两个数谁大谁小,参数输入错误,则自定义退出,整数是通过命令行参数传递;

vimj.sh
#!/bin/bash
#
if [ $# -lt 2 ]; then
    echo “Stupid...”
    echo “Usage: `basename $0` argu1 argu2”
    exit 4
fi 
 
if[ $1 �gt $2 ]; then
    echo “The max num is $1.”
else
    echo “The max num is $2”
fi
#bash j.sh 3
Stupid...
Usage:j.sh argu1 argu2
#bash j.sh 3 6
The max num is 6

(14)让用户通过键盘输入一个用户名,如果用户存在,就显示其用户名和UID;否则,就显示用户不存在;

#!/bin/bash
#
read �t 10 �p “Enter a username: ”username
if id $userName &> /dev/null; then
    userID=`id �u $userName`
    echo “$userName: $userID”
else
    echo “$userName not exist.”
fi

(15)让用户通过键盘输入一个用户名,如果用户不存在就退出;如果其UID等于其GID,就说他是“good guy” 否则,就说他是个“bad guy”;

#!/bin/bash
#
read -t 10 -p "Enter a username: " userName
if ! id $userName &> /dev/null; then
    echo "$userName not exist."
    exit 6
fi

if [ `id -u $userName` -eq `id -g $userName` ]; then
    echo "Good guy"
else
    echo "Bad guy"
fi

(16)添加10个用户stu1-stu10;但要先判断用户是否存在;

如果存在,就用红色显示其已经存在;

否则,就添加此用户,并绿色显示;

最后显示一共添加了几个用户;

vim user.sh
#!/bin/bash
#
declare -i userCount=0
for i in {1..10}; do
    if id stu$i &> /dev/null; then
        echo -e "\033[31mstu$i\033[0m exists."
    else
        useradd stu$i && echo -e "add \033[32mstu$i\033[0m finished."
        let userCount++
    fi
done
echo "Add $userCount users."

# bash user.sh 
add stu1 finished.
add stu2 finished.
add stu3 finished.
add stu4 finished.
add stu5 finished.
add stu6 finished.
add stu7 finished.
add stu8 finished.
add stu9 finished.
add stu10 finished.
Add 10 users.

2、字符测试

    双目:

    >:大于

    <:小于

    ==:等于,等值比较

    =~:左侧字符串是否能够被右侧的PATTREN所匹配(包含)

 ==:

# stringA="root"
# stringB="root"
# [ "$stringA" == "$stringB" ]
# echo $?
0
测试是否相等?结果是肯定的。

 =~: 测试userName变量中的值是否包含了“ot”这样的字符串;

# userName=root
# [[ "$userName" =~ ot ]]
# echo $?
0

给一个用户名,判断这个用户的shell是不是以“sh”结尾的;

#userName=root
#$[[ `grep "^$userName\>" /etc/passwd | cut -d: -f7` =~ sh$ ]]
#echo $?
0


    单目:

    -n $stringVar:字符串是否不空,不空为真,空则为假;

测试stringA是否非空,非空为真,否则为假;

#stringA=root
# [ -n "$stringA" ]
# echo $?
0


    -z $stringVar: 字符串是否为空,空则为真,不空则假;

测试stringA是否为空,空则真,否则为假;

# [ -z "$stringA" ]
# echo $?
1

3、文件测试

测试表达式:

    test 测试表达式

    [ 测试表达式 ]

    [[ 测试表达式 ]]


    单目测试:

    -e file:测试文件是否存在;存在为真,否则为假;

    -a file: 和-e一样

   文件类型测试

     -f /path/to/file:测试是否为普通文件;

    -d /path/to/somefile:测试是否为目录文件;

    -b /path/to/somefile:测试文件是否存在并且是否是一个块设备文件;

    -c /path/to/somefile:测试是否为字符设备文件;

    -h或者-L /path/to/somefile:测试文件是否存在并且为符号链接文件;

    -p /path/to/somefile:测试文件是否存在并且为管道文件;

    -S /path/to/somefile:测试文件是否存在并且为套接字文件;

    -s /path/to/somefile:测试文件是否不空,不空为真,否则为假;

    文件的权限测试:

    -r /path/to/somefile:测试当前用户对此文件是否有读权限;

    -w /path/to/somefile:测试当前用户对此文件是否有写权限;

    -x /path/to/somefile:测试当前用户对此文件是否有执行权限;

    

    双目测试:

    file1 -nt file2:测试file1是否比file2更新一些;

    file1 -ef file2: 是否指向同一文件系统的相同inode的硬链接;

    file1 -ot file2: file1文件是否旧于file2


示例:

(17)

#vim download.sh

#!/bin/bash
#
url=`http://172.16.0.1/centos6.5.repo`
which wget &> /dev/null || exit 5

downloader=`which wget`

[ -x $downloader ] || exit 6

$downloader $url

#bash download.sh

Shell编程之算数、条件测试read详解二(待续...)_第2张图片

(18)

分别复制/var/log下的文件至/tmp/logs/目录中;

复制目录时,才使用cp -r

复制文件时,才使用cp

复制链接文件,使用cp -d

如果是其他文件,使用cp -a

vim cplog.sh

#!/bin/bash
#
targetDir='/tmp/logs'

[ -e $targetDir ] || mkdir $targetDir

for fileName in /var/log/*; do
    if [ -d $fileName ]; then
        copyCommand='cp -r'
    elif [ -f $fileName ]; then
        copyCommand='cp'
    elif [ -h $fileName ]; then
        copyCommand='cp -d'
    else
        copyCommand='cp -a'
    fi
    
    $copyCommand $fileName $targetDir
done








你可能感兴趣的:(基础,bash,条件)