Shell编程

137 阅读3分钟

查看Linux系统支持的shell类型

[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash

快速入门

  • 新建/usr/shell/hello.sh,使用vim编辑其内容
#!/bin/bash
echo 'Hello world!'
  • 执行脚本
/bin/sh hello.sh
或
/bin/bash hello.sh

`sh`是`bash`的快捷方式(软连接)

shell变量

定义变量

变量名=变量值
eg:username='zhangsan'

变量命名规则:
命名中只能使用英文字母、数字和下划线,首字母不能以数字开头
中间不能有空格,可以使用下划线(_)
不能使用标点符号
不能使用bash里的关键字(使用help命令查看保留关键字)

使用变量

#定义变量
name='tom'
#使用变量
echo $name
echo ${name}
  • 使用语句给变量赋值
for file in `ls /etc`
或
for file in $(ls /etc)
  • 只读变量
readonly 变量名
  • 删除变量
unset 变量名
#不能删除只读变量

字符串变量

#定义字符串
city1='北京'
city2="上海"
city3=深圳
#字符串引用字符串
skill='java'
str="I good at $skill"
#获取字符串长度
echo ${#skill} ${#str} # 4 14
#提取子字符串
str="I like java"
echo ${str:2} #类似于Java中的substring(2) 
echo ${str:2:2} #类似于Java中的substring(2,2)
#查找子字符串
str="java is so easy"
echo `expr index "$str" o` #下表从1开始

注释

#单行注释
使用`#`进行单行注释
#多行注释
:<<EOF
注释内容
注释内容
注释内容
EOF
或者
:<<!
注释内容
注释内容
注释内容
!

数组

定义数组

#方式1
数组名=(value1,value2...)
#方式2
数组名[0]=value0
数组名[1]=value1
数组名[2]=value2

读取数组

${数组名[index]} #数组下标
#获取所有元素
${数组名[*]}
${数组名[@]}
#获取数组长度
${#数组名[*]}
${#数组名[@]}

参数传递

#!/bin/bash
#test05内容
echo "接收第一个参数:$0"
echo "接收第二个参数:$1"
echo "接收第三个参数:$2"
echo "接收第四个参数:$3"
[root@localhost test]# ./test05.sh a b c d e
接收第一个参数:./test05.sh
接收第二个参数:a
接收第三个参数:b
接收第四个参数:c

几个特殊字符用来处理参数

参数处理说明
$#传递到脚本的参数个数
$*以一个字符串显示所有向脚本传递的参数。如"$*"""括起来的情况、以"$1 $2 ... $n"的形式输出所有参数
$$脚本运行的当前进程ID
$!后台运行的最后一个进程的ID
$@$*相同,但使用时加引号,并在引号中返回每个参数。如"$@"""括起来的情况、以"$1 $2 ... $n"的形式输出所有参数
$-显示Shell使用的当前选项,与set命令功能相同
$?显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误

例子:

#!/bin/bash
#test07内容
echo "shell的参数传递"
echo "第一个参数:$1"
echo "接收参数的个数:$#"
echo "接收所有的参数:$*"
echo "接收参数:$@"
[root@localhost test]# ./test06.sh 1 2 3 4 aa bb
shell的参数传递
第一个参数:1
接收参数的个数:6
接收所有的参数:1 2 3 4 aa bb
接收参数:1 2 3 4 aa bb

运算符

  • 算术运算符

    设a=10,b=20

    运算符说明举例
    +加法expr $a + $b结果为30
    -减法expr $a - $b结果为 -10
    *乘法expr $a * $b结果为200
    /除法expr $b / $a结果为2
    %取余expr $a % $b结果为0
    =赋值a = $b把变量b的值赋给a
    ==相等。用于比较两个数字,相同则返回true[$a == $b]返回false
    !=不相等。用于比较两个数字,不相等则返回true[$a != $b]返回true
  • 关系运算符

    设a=10,b=20

    运算符说明举例
    -eq检测两个数是否相等,相等返回true[$a -eq $b]返回false
    -ne检测两个数是否不相等,不相等返回true[$a -ne $b]返回true
    -gt检测左边的数是否大于右边的数,如果是,则返回true[$a -gt $b]返回false
    -lt检测左边的数是否小于右边的数,如果是,则返回true[$a -lt $b]返回true
    -ge检测左边的数是否大于等于右边的数,如果是,则返回true[$a -ge $b]返回false
    -le检测左边的数是否小于等于右边的数,如果是,则返回true[$a -le $b]返回true

流程控制

if语句

  • if语句格式

    if condition
    then
        command1
        command2
        ...
    fi
    
  • if.else语句

    if condition
    then
        command1
        command2
        ...
    else
        command1
        command2
        ...
    fi
    
  • if..elif..else

    if condition1
    then
        command1
    elif condition2
        command2
    else
        command3
    fi
    

for循环

for variable in (list); 
do
command
...
done

while循环

while condition; do
command
done

case

case 值 in
    模式1)
        command1
        command2
        ...
        ;;
    模式2)
        command3
        command4
        ...
        ;;
    ...
    *)
        command
        ...
esac

跳出循环

  • break命令

    #!/bin/bash
    i=0;
    while true; do
            sleep 1
            echo $i `date + "%Y-%m-%d %H:%M:%S"`
            i=$[ i + 1 ]
            if [ $i -eq 10 ]; then
                break
            fi
    done
    
  • continue命令

    #!/bin/bash
    for i in {1..30}; do
        if test $[ 1 % 3 ] -eq 0; then
            continue
        fi
        echo $i
    done
    

函数使用

#functionreturn可写可不写
[ function ] funName(){
    action;
    [ retrun int; ]
} 

传递参数给函数

#!/bin/bash
fun(){
    echo "第一个参数为$1!"
    echo "第二个参数为$2!"
    echo "第十个参数为$10!"
    echo "第十个参数为${10}!"
    echo "第十一个参数为${11}!"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
fun 1 2 3 4 5 6 7 8 9 34 73

#输出结果
第一个参数为1!
第二个参数为2!
第十个参数为10!
第十个参数为34!
第十一个参数为73!
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !

shell脚本案例

  • 统计 /etc /var /usr 这三个目录下共有多少个一级目录和文件

    #!/bin/bash
    #编写一个sumfile.sh统计 /etc /var /usr 这三个目录下共有多少个一级目录和文件
    num1=$(ls -l /etc | wc -l)
    num2=$(ls -l /var | wc -l)
    num3=$(ls -l /usr | wc -l)
    #sum=$(( num1 + num2 + num3 ))
    let sum=$num1+$num2+$num3
    echo "/etc /var /usr 这三个目录下共有$sum个一级目录和文件"
    
  • 猜数字

    #!/bin/bash
    #编写脚本,随机生成一个100以内的数字,提示用户猜数字,
    #根据用户的输入提示用户是否猜对了,猜大了,提示猜大了;猜小了,提示猜小了
    #一直循环直到猜对了
    num=$[RANDOM%100+1]
    while :
    do
            read -p "计算器生成一个1-100的随机数" cat
            if [ $cat -eq $num ];then
                    echo "猜对了!"
                    break
            elif [ $cat -le $num ];then
                    echo "猜小了!"
            else
                    echo "猜大了!"
            fi
    done
    
  • 使用case、while和read查看系统信息

    #!/bin/bash
    :<<!
            编写一个交互脚本,执行脚本时键盘输入对应的参数,脚本反馈对应信
    息,当输入“exit”时推出脚本,脚本采用read捕捉键盘输入信息,然后
    使用case进行条件选择并执行命令,最后使用while对case语句进行循环
    !
    
    #展示信息供用户选择
    cat << EOF
    D|d 显示硬盘信息
    M|m 显示内存信息
    S|s 显示交互分区信息
    EOF
    
    read -p "请输入以上参数:" param
    while [ $param != "exit" ];do
            case $param in
                    D|d)
                            df -h
                            ;;
                    M|m)
                            free -m | grep Mem
                            ;;
                    S|s)
                            free -m | grep Swap
                            ;;
                    *)
                            echo "Ukown"
            esac
            read -p "请再次输入以上参数:" param
    done