LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 330|回复: 0

shell脚本进阶

[复制链接]
发表于 2023-12-13 14:08:27 | 显示全部楼层 |阅读模式
本帖最后由 xhz 于 2023-12-13 14:19 编辑

流程控制
1、顺序执行
2、选择执行
3、循环执行
条件选择if语句

  1. echo "单分支"
  2. if [ $id -gt 0 ];then echo $id;fi
  3. echo "双分支"
  4. if [ $id -gt 0 ];then echo $id;else echo 0;fi
  5. echo "多分支"
  6. if [ $id -gt 0 ];then \
  7.     echo $id\
  8. elif [ $id -eq 0 ];then \
  9.     echo 0\
  10. else echo "null" fi
  11. case语句
  12. case 变量引用 in
  13. PAT1)
  14.     分支1
  15.     ;;
  16. PAT2)
  17.     分支2
  18.     ;;
  19.     ...
  20. *)
  21.     默认分支
  22.     ;;
  23. esac
复制代码

循环语句

  1. for循环

  2. #第一种
  3. for 变量名 in 列表;do
  4.     循环体
  5. done
  6. #第二种
  7. for ((控制变量初始化;条件判断表达式;控制变量的修正表达式))
  8. do
  9.     循环体
  10. done
复制代码

列表生成方式   

  1.     直接给出列表    整数列表{start..end},$(seq [start [step]] end)
  2.     返回命令:$(command)
  3.     变量引用:$@,$*
  4.    
复制代码



for i in {1..10};do echo $i;done
while循环

while CONDITION; do
    循环体
done
进入条件:CONDITION为真
退出条件:CONDITION为假


i=0;while [ $i -lt 10 ];do echo $i; let i++;done
until循环

until CONDITION; do
    循环体
done
进入条件:CONDITION为假
退出条件:CONDITION为真
i=0;until [ $i -gt 10 ];do echo $i; let i++;done
创建无限循环

while true; do
    循环体
done
until false; do
    循环体
Done
特殊用法

#while循环的特殊用法(遍历文件的每一行):
while read line; do
    循环体
done < /PATH/FROM/SOMEFILE
控制循环语句continue,break:这个和其他编程语言是一样的,不做过多的介绍

循环控制shift命令
shift [n]:用于将参数列表向左移动n位
一旦参数开始移动,最左边的参数将会删除
#!/bin/bash
# Name: doit.sh
# Purpose: shift through command line arguments
# Usage: doit.sh [args]
#打印所有参数
while (( $# > 0 ))
do
    echo $*
    shift
done
定义函数
# 函数由两部分组成:函数名和函数体。
# 语法一:
function f_name {
    ...函数体...
}
#语法二:
function f_name () {
    ...函数体...
}
# 语法三:
f_name (){
    ...函数体...
}

# 函数有两种返回值:
# 函数的执行结果返回值:
    (1) 使用echo等命令进行输出
    (2) 函数体中调用命令的输出结果
# 函数的退出状态码:
    (1) 默认取决于函数中执行的最后一条命令的退出状态码
    (2) 自定义退出状态码,其格式为:
        return 从函数中返回,用最后状态命令决定返回值
        return 0 无错误返回。
        return 1-255 有错误返回
#!/bin/bash
# func1
hello() {
    echo "Hello there today's date is `date +%F`"
}
echo "now going to the function hello"
hello
echo "back from the function"
在脚本中加载其他脚本或者函数文件

echo "1"
. filename
echo "2"
source filename
函数参数

函数可以接受参数:
    传递参数给函数:调用函数时,在函数名后面以空白分隔
给定参数列表即可;例如“testfunc arg1 arg2 ...”
    在函数体中当中,可使用$1, $2, ...调用这些参数;还可以使用$@, $*, $#等特殊变量
函数递归

echo "实现n的阶乘"
fact() {
    if [ $1 -eq 0 -o $1 -eq 1 ]; then
        echo 1
    else
        echo $[$1*$(fact $[$1-1])]
    fi
}
fact $1
数组
变量:存储单个元素的内存空间
数组:存储多个元素的连续的内存空间,相当于多个变量的集合
数组名和索引
    索引:编号从0开始,属于数值索引
    注意:索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引,bash4.0版本之后开始支持
    bash的数组支持稀疏格式(索引不连续)
声明数组:
    declare -a ARRAY_NAME
    declare -A ARRAY_NAME: 关联数组
数组赋值

(1) 一次只赋值一个元素;
    ARRAY_NAME[INDEX]=VALUE
    weekdays[0]="Sunday"
    weekdays[4]="Thursday"
(2) 一次赋值全部元素:
    ARRAY_NAME=("VAL1" "VAL2" "VAL3" ...)
(3) 只赋值特定元素:
    ARRAY_NAME=([0]="VAL1" [3]="VAL2" ...)
(4) 交互式数组值对赋值
    read -a ARRAY
引用数组

引用数组元素:${ARRAY_NAME[INDEX]}
    注意:省略[INDEX]表示引用下标为0的元素
数组的长度(数组中元素的个数):
    ${#ARRAY_NAME}
    ${#ARRAY_NAME[@]}
#编写脚本,定义一个数组,数组中的元素是/var/log目录下所有以.log结尾的文件;要统计其下标为偶数的文件中的行数之和

  1. #!/bin/bash
  2. #
  3. declare -a files
  4. files=(/var/log/*.log)
  5. declare -i lines=0
  6. for i in $(seq 0 $[${#files}-1]); do
  7.     if [ $[$i%2] -eq 0 ];then
  8.         let lines+=$(wc -l ${files[$i]} | cut -d' ' -f1)
  9.     fi
  10. done
  11. echo "Lines: $lines."
复制代码

数组数据处理

引用数组中的元素:
    所有元素:${ARRAY[@]}, ${ARRAY}
    数组切片:${ARRAY[@]ffset:number}
        offset: 要跳过的元素个数
        number: 要取出的元素个数
        取偏移量之后的所有元素
            ${ARRAY[@]ffset}
向数组中追加元素:
    ARRAY[${#ARRAY}]
删除数组中的某元素:导致稀疏格式
    unset ARRAY[INDEX]
关联数组:
    declare -A ARRAY_NAME 注意:必须先声明,再调用
    ARRAY_NAME=([idx_name1]='val1' [idx_name2]='val2‘...)
字符串处理

  1. 基于切片去字符
  2. ${#var}:返回字符串变量var的长度
  3. ${var:offset}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到最后的部分,offset的取值在0 到 ${#var}-1 之间(bash4.2后,允许为负值)
  4. ${var:offset:number}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,长度为number的部分
  5. ${var: -length}:取字符串的最右侧几个字符  注意:冒号后必须有一空白字符
  6. ${var:offset:-length}:从最左侧跳过offset字符,一直取到字符串的最右侧lengh个字符之前
  7. ${var: -length:-offset}:从最右侧向左取到length个字符开始,再向右取到距离最右侧offset个字符之间的内容
复制代码


  1. 基于模式取子串:
  2. ${var#*word}:其中word可以是指定的任意字符 功能:自左而右,查找var变量所存储的字符串中,第一次出现的word, 删除字符串开头至第一次出现word字符之间的所有字符
  3. ${var##*word}:同上,不同的是,删除的是字符串开头至最后一次由word指定的字符之间的所有内容
  4. 示例:
  5.     file="var/log/messages“
  6.     ${file#*/}: log/messages
  7.     ${file##*/}: messages
  8. ${var%word*}:其中word可以是指定的任意字符;功能:自右而左,查找var变量所存储的字符串中,第一次出现的word, 删除字符串最后一个字符向左至第一次出现word字符之间的所有字符;
  9.     file="/var/log/messages"
  10.     ${file%/*}: /var/log
  11. ${var%%word*}:同上,只不过删除字符串最右侧的字符向左至最后一次出现word字符之间的所有字符;
  12. 示例:
  13.     url=http://www.magedu.com:80
  14.     ${url##*:} 80
  15.     ${url%%:*} http
复制代码


  1. 查找替换:
  2. ${var/pattern/substi}:查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substi替换之
  3. ${var//pattern/substi}: 查找var所表示的字符串中,所有能被pattern所匹配到的字符串,以substi替换之
  4. ${var/#pattern/substi}:查找var所表示的字符串中,行首被pattern所匹配到的字符串,以substi替换之
  5. ${var/%pattern/substi}:查找var所表示的字符串中,行尾被pattern所匹配到的字符串,以substi替换之查找并删除:
  6. ${var/pattern}:查找var所表示的字符串中,删除第一次被pattern所匹配到的字符串
  7. ${var//pattern}:所有
  8. ${var/#pattern}:行首
  9. ${var/%pattern}:行尾
复制代码


字符大小写转换:

  1. ${var^^}:把var中的所有小写字母转换为大写
  2. ${var,,}:把var中的所有大写字母转换为小写
  3. 变量赋值
  4. ${var:-value}:如果var为空或未设置,那么返回value;否则返回var的值, 可省略:
  5. ${var:+value}:如果var不空,则返回value,否则返回空值
  6. ${var:=value}:如果var为空或未设置,那么返回value,并将value赋值给var;否则返回var的值
  7. ${var:?error_info}:如果var为空或未设置,那么在当前终端打印error_info;否则返回var的值

  8. 为脚本程序使用配置文件,实现变量赋值
  9.     (1) 定义文本文件,每行定义“name=value”
  10.     (2) 在脚本中source此文件即可
复制代码



您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表