• 22.shell脚本学习


    linuxshell脚本学习笔记:

    复制了一下,然后一个一个向过看的时候发现好多啊。然后下面给了链接。学习请看菜鸟教程:https://www.runoob.com/linux/linux-shell-basic-operators.html

    变量:

    d= `date+%H:%M:%S`   需要用到``反引号
    echo "the script end at $d"  使用变量
    for file in $(ls /etc) 循环变量
    
    for skill in Ada Coffe Action Java; do 
        echo "I am good at ${skill}Script"  # 这里的花括号可以不加
    done
    
    使用一个定义过的变量,只要在变量名前面加美元符号即可:
    your_name="qinjx"
    echo $your_name
    echo ${your_name}  # 加不加{}都可以,加上只是为了方便区分
    echo "I am good at ${skill}Script" # 这种就需要加上,因为连在一起了
    # 只读变量
    #!/bin/bash
    myUrl="http://www.google.com"
    readonly myUrl
    myUrl="http://www.runoob.com"  # 这个变量名不能再用
    # 删除变量
    unset variable_name  # 变量被删除后不能再次使用。unset 命令不能删除只读变量。
    # 变量类型
    # 运行shell时,会同时存在三种变量:
    
    1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
    2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
    3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
    
    # 字符串
    str='this is a string'
    单引号字符串的限制:
    单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
    单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
    # 双引号
    your_name='runoob'
    str="Hello, I know you are "$your_name"! 
    "
    echo -e $str
    
    # 双引号的优点:
    双引号里可以有变量
    双引号里可以出现转义字符
    
    # 字符串拼接
    your_name="runoob"
    # 使用双引号拼接
    greeting="hello, "$your_name" !"
    greeting_1="hello, ${your_name} !"
    echo $greeting  $greeting_1
    # 使用单引号拼接
    greeting_2='hello, '$your_name' !'
    greeting_3='hello, ${your_name} !'
    echo $greeting_2  $greeting_3
    
    # 获取字符串长度
    string="abcd"
    echo ${#string} #输出 4
    
    # 提取字符串
    string="runoob is a great site"
    echo ${string:1:4} # 输出 unoo
    
    # 查找字符串
    string="runoob is a great site"
    echo `expr index "$string" io`  # 输出 4
    
    数组:
    在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:
    array_name=(
    value0
    value1
    value2
    value3
    )
    
    # 读取数组与赋值 ${数组名[index]}
    array_name[0]=value0
    array_name[1]=value1
    array_name[n]=valuen
    
    valuen=${array_name[n]}
    echo ${array_name[@]} # 读取数组全部内容
    
    # 获取数组长度
    # 取得数组元素的个数
    length=${#array_name[@]}
    # 或者
    length=${#array_name[*]}
    # 取得数组单个元素的长度
    lengthn=${#array_name[n]}
    
    # 多行注释
    :<<'
    注释内容...
    注释内容...
    注释内容...
    '
    
    :<<!
    注释内容...
    注释内容...
    注释内容...
    !
    

    shell传递参数:

    echo "Shell 传递参数实例!";
    echo "执行的文件名:$0";
    echo "第一个参数为:$1";
    echo "第二个参数为:$2";
    echo "第三个参数为:$3";
    
    $ chmod +x test.sh 
    $ ./test.sh 1 2 3
    Shell 传递参数实例!
    执行的文件名:./test.sh
    第一个参数为:1
    第二个参数为:2
    第三个参数为:3
    
    $# 传递到脚本的参数个数
    $* 以一个单字符串显示所有向脚本传递的参数。 如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
    $$ 脚本运行的当前进程ID号
    $! 后台运行的最后一个进程的ID号
    $@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。 如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
    $- 显示Shell使用的当前选项,与set命令功能相同。
    $? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
    echo "Shell 传递参数实例!";
    echo "第一个参数为:$1";
    echo "参数个数为:$#";
    echo "传递的参数作为一个字符串显示:$*";
    
    $ chmod +x test.sh 
    $ ./test.sh 1 2 3
    Shell 传递参数实例!
    第一个参数为:1
    参数个数为:3
    传递的参数作为一个字符串显示:1 2 3
    
    
    # $* 与 $@ 区别:
    相同点:都是引用所有参数。
    不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。
    echo "-- $* 演示 ---"
    for i in "$*"; do
        echo $i
    done
    
    echo "-- $@ 演示 ---"
    for i in "$@"; do
        echo $i
    done
    
    # 输出结果:
    $ chmod +x test.sh 
    $ ./test.sh 1 2 3
    -- $* 演示 ---
    1 2 3
    -- $@ 演示 ---
    1
    2
    3
    

    判断:

    read -p "please input your score:" a
    if ((a<60)); then   #这里必须是(())双括号
    	echo "you didn't pass the exam"
    fi
    

    带有else的判断:

    read -p "please input your score:" a
    if ((a<60)); then   #这里必须是(())双括号
    	echo "you didn't pass the exam"
    else 
    	echo "Good,you pass the exam"
    fi
    

    带有elif:

    read -p "please input your score:" a
    if ((a<60)); then   #这里必须是(())双括号
    	echo "you didn't pass the exam"
    elif ((a>60)) && ((a<85)); then  # &&并且 ||或者
    	echo "Good,you pass the exam"
    else 
    	echo "Good,you score is very hight"
    fi
    
    但是就不能使用>, < , = 这样的符号了,要使用 -lt (小于),-gt (大于),-le (小于等于),-ge (大于等于),-eq (等于),-ne (不等于)。
    

    文本判断:

    shell 脚本中if还经常判断关于档案属性,比如判断是普通文件还是目录,判断文件是否有读写执行权限等。常用的也就几个选项:
    
    -e :判断文件或目录是否存在
    
    -d :判断是不是目录,并是否存在
    
    -f :判断是否是普通文件,并存在
    
    -r :判断文档是否有读权限
    
    -w :判断是否有写权限
    
    -x :判断是否可执行
    
    使用if判断时,具体格式为: if [ -e filename ] ; then
    

    case语句:

    在shell 脚本中,除了用if来判断逻辑外,还有一种常用的方式,那就是case了。具体格式为:
    
    case 变量 in
    
    value1)
    
    command
    
    ;;
    
    value2)
    
    command
    
    ;;
    
    value3)
    
    command
    
    ;;
    
    *)
    
    command
    
    ;;
    
    esac
    
    例如:
    	read -p "please input your score:" n
    	a = $[$n%2]
    	case $a in 
    	1)
    		echo "then number is odd"
    		;;
    	0)
    		echo "the number is even"
    		;;  # 这个东西必须写
    	esac
    	
    

    循环for:

    for 变量名 in 循环的条件; do
    
    command
    
    done
    例如:
        for i in `seq 1 5`;do
            echo $i
        done
    也可以写成一句话:
    	for i in `ls`; do echo $i; done 和 for i in `cat test.txt`; do echo $i; done
    

    循环while:

    while 条件; do
    
    command
    
    done
    例如:
    	a = 10
    	while [ $a -ge 1];do
    		echo "$a"
    		a = $[$a-1]
    	done
    

    函数:

    • 1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。

    • 2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)

      注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。

    function 函数名() {
    command
    }
    例如:
        function sum(){
            sum = $[$1 + $2]
            echo $sum
        }
        sum $1 $2 这里定义的形参
    
    funWithParam(){
        echo "第一个参数为 $1 !"
        echo "第二个参数为 $2 !"
        echo "第十个参数为 $10 !"
        echo "第十个参数为 ${10} !"
        echo "第十一个参数为 ${11} !"
        echo "参数总数有 $# 个!"
        echo "作为一个字符串输出所有参数 $* !"
    }
    funWithParam 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 !
    
    # 注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
    
    1. 编写shell脚本,计算1-100的和;
    for i in `seq 1 100`;do
    	sum = $[$i + $sum]
    done
    echo $sum
    2. 编写shell脚本,要求输入一个数字,然后计算出从1到输入数字的和,要求,如果输入的数字小于1,则重新输入,直到输入正确的数字为止;
    n = 0
    while [$n -le "1"];do
    	read -p "please input a number:" a
    done
    sum = 0
    for i in `1 n`;do
    	sum = $[$i + $sum]
    done 
    echo $sun
    3. 编写shell脚本,把/root/目录下的所有目录(只需要一级)拷贝到/tmp/目录下;
    #! /bin/bash
    cd /root/
    for f in "ls /root/";do
    	if [-d $f];then
    	 	cp -r $f /tmp/
    	 fi
    done
    4. 编写shell脚本,批量建立用户user_00, user_01, … ,user_100并且所有用户同属于users组;
        4. #! /bin/bash
    
        groupadd users
    
        for i in `seq 0 9`; do
    
        useradd -g users user_0$i
    
        done
    
        for j in `seq 10 100`; do
    
        useradd -g users user_$j
    
        done
    
    5. 编写shell脚本,截取文件test.log中包含关键词’abc’的行中的第一列(假设分隔符为”:”),然后把截取的数字排序(假设第一列为数字),然后打印出重复次数超过10次的列;
    	5. #! /bin/bash
    
        awk -F':' '$0~/abc/ {print $1}' test.log >/tmp/n.txt
    
        sort -n n.txt |uniq -c |sort -n >/tmp/n2.txt
    
        awk '$1>10 {print $2}' /tmp/n2.txt
    
    6. 编写shell脚本,判断输入的IP是否正确(IP的规则是,n1.n2.n3.n4,其中1<n1<255, 0<n2<255,="" 0<n3<255,="" 0<n4<255<="" span="">)。	
    6. #! /bin/bash
    
    checkip() {
    
    if echo $1 |egrep -q '^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$' ; then
    
    a=`echo $1 | awk -F. '{print $1}'`
    
    b=`echo $1 | awk -F. '{print $2}'`
    
    c=`echo $1 | awk -F. '{print $3}'`
    
    d=`echo $1 | awk -F. '{print $4}'`
    
    for n in $a $b $c $d; do
    
    if [ $n -ge 255 ] || [ $n -le 0 ]; then
    
    echo "the number of the IP should less than 255 and greate than 0"
    
    return 2
    
    fi
    
    done
    
    else
    
    echo "The IP you input is something wrong, the format is like 192.168.100.1"
    
    return 1
    
    fi
    
    }
    
    rs=1
    
    while [ $rs -gt 0 ]; do
    
    read -p "Please input the ip:" ip
    
    checkip $ip
    
    rs=`echo $?`
    
    done
    
    echo "The IP is right!"
    

    tr命令:

    tr -c -d -s [“string1_to_translate_from”] [“string2_to_translate_to”] < input-file
    
    -c 用字符串1中字符集的补集替换此字符集,要求字符集为ASCII。
    -d 删除字符串1中所有输入字符。
    -s 删除所有重复出现字符序列,只保留第一个;即将重复出现字符串压缩为一个字符串。
    input-file是转换文件名。虽然可以使用其他格式输入,但这种格式最常用。
    字符范围
    指定字符串1或字符串2的内容时,只能使用单字符或字符串范围或列表。
    [a-z] a-z内的字符组成的字符串。
    [A-Z] A-Z内的字符组成的字符串。
    [0-9] 数字串。
    octal 一个三位的八进制数,对应有效的ASCII字符。
    [O*n] 表示字符O重复出现指定次数n。因此[O*2]匹配OO的字符串。
    tr中特定控制字符的不同表达方式
    速记符含义八进制方式
    a Ctrl-G 铃声07
     Ctrl-H 退格符10
    f Ctrl-L 走行换页14
    
     Ctrl-J 新行12
    
     Ctrl-M 回车15
    	 Ctrl-I tab键11
    v Ctrl-X 30
    实例:
    将文件file中出现的”abc”替换为”xyz”
    
    # cat file | tr “abc” “xyz” > new_file
    
    【注意】这里,凡是在file中出现的”a”字母,都替换成”x”字母,”b”字母替换为”y”字母,”c”字母替换为”z”字母。而不是将字符串”abc”替换为字符串”xyz”。
    
    2、使用tr命令“统一”字母大小写
    (小写 –> 大写)
    # cat file | tr [a-z] [A-Z] > new_file
    (大写 –> 小写)
    # cat file | tr [A-Z] [a-z] > new_file
    
    3、把文件中的数字0-9替换为a-j
    
    # cat file | tr [0-9] [a-j] > new_file
    
    4、删除文件file中出现的”Snail”字符
    
    # cat file | tr -d “Snail” > new_file
    
    【注意】这里,凡是在file文件中出现的’S’,’n’,’a’,’i’,’l’字符都会被删除!而不是紧紧删除出现的”Snail”字符串。
    
    5、删除文件file中出现的换行’
    ’、制表’	’字符
    
    # cat file | tr -d “
    	” > new_file
    
    不可见字符都得用转义字符来表示的,这个都是统一的。
    
    6、删除“连续着的”重复字母,只保留第一个
    
    # cat file | tr -s [a-zA-Z] > new_file
    
    7、删除空行
    
    # cat file | tr -s “
    ” > new_file
    
    8、删除Windows文件“造成”的’^M’字符
    
    # cat file | tr -d “
    ” > new_file
    或者
    # cat file | tr -s “
    ” “
    ” > new_file
    
    【注意】这里-s后面是两个参数”
    ”和”
    ”,用后者替换前者
    
    9、用空格符40替换制表符11
    
    # cat file | tr -s “11” “40” > new_file
    
    10、把路径变量中的冒号”:”,替换成换行符”
    ”
    
    # echo $PATH | tr -s “:” “
    ”
    

    运算符:

    Shell 和其他编程语言一样,支持多种运算符,包括:
    
    算数运算符
    关系运算符
    布尔运算符
    字符串运算符
    文件测试运算符
    原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
    expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
    例如,两个数相加(注意使用的是反引号 ` 而不是单引号 '):
    
    两点注意:
    表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
    完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。
    
    + 加法 expr $a + $b 结果为 30。
    - 减法 expr $a - $b 结果为 -10。
    * 乘法 expr $a * $b 结果为 200。
    / 除法 expr $b / $a 结果为 2。
    % 取余 expr $b % $a 结果为 0。
    = 赋值 a=$b 将把变量 b 的值赋给 a。
    != 不相等。用于比较两个数字,不相同则返回 true。 [ $a != $b ] 返回 true。
    == 相等。用于比较两个数字,相同则返回 true。 [ $a == $b ] 返回 false。

    关于echo:

    #!/bin/sh
    echo -e "OK! c" # -e 开启转义 c 不换行
    echo "It is a test"
    
    OK! It is a test
    
    # 定向输出
    echo "It is a test" > myfile
    
    # 原字符串输出可以使用单引号
    echo '$name"'
    $name"
    
    # 显示执行结果
    echo `date`  反引号
    

    printf:

    printf "%-10s %-8s %-4s
    " 姓名 性别 体重kg  
    printf "%-10s %-8s %-4.2f
    " 郭靖 男 66.1234 
    printf "%-10s %-8s %-4.2f
    " 杨过 男 48.6543 
    printf "%-10s %-8s %-4.2f
    " 郭芙 女 47.9876 
    
    姓名     性别   体重kg
    郭靖     男      66.12
    杨过     男      48.65
    郭芙     女      47.99
    
    %s %c %d %f都是格式替代符
    
    %-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
    %-4.2f 指格式化为小数,其中.2指保留2位小数。
    

    test:

    菜鸟教程

    # 代码中的 [] 执行基本的算数运算,如
    num1=$[2*3]
    num2=$[1+5]  # 不能有空格
    if test $[num1] -eq $[num2]  # test,后面的[]里面没有空格
    then
        echo '两个数字相等!'
    else
        echo '两个数字不相等!'
    fi
    
    
    a=10
    b=20
    if [ $a == $b ]  # 必须有空格
    then
       echo "a 等于 b"
    elif [ $a -gt $b ]
    then
       echo "a 大于 b"
    elif [ $a -lt $b ]
    then
       echo "a 小于 b"
    else
       echo "没有符合的条件"
    fi
    
    
  • 相关阅读:
    机器学习算法的流程总结
    机器学习算法的流程总结
    路由器的原理
    路由器的原理
    机器学习编程接口(api)设计(oop 设计)
    机器学习编程接口(api)设计(oop 设计)
    组态档(configuration file)与建构档
    组态档(configuration file)与建构档
    学习之法 —— 套路
    学习之法 —— 套路
  • 原文地址:https://www.cnblogs.com/liuzhanghao/p/12030745.html
Copyright © 2020-2023  润新知