zoukankan      html  css  js  c++  java
  • bash脚本的特性01

    1.bash特性之多命令执行

    1. cmd
    2. cmd1 `cmd2` #引用
    3. cmd1 | cmd2 | cmd3 | ... #管道
    逻辑组合:
    cmd1 && cmd2 && ...   与
    cmd1 || cmd2 || ...          或
    !cmd1                         非
    逻辑运算:
    运算数:true,false
    返回值:0(true),false(1-255)
    与:
    true && true = true
    true && false = false
           第一个操作数为true,其结果将取决于第二个操作数;
    false && true = false
    false && false = false
            第一个操作数为False,其结果至此可断定,为false;
     
    或:
    true || true = true
    true || false = true
           第一个操作数为true,其结果至此可断定,为true;
    false || true = true
    false || false = false
          第一个操作数为false,其结果将取决于第二个操作数;                   
     
    非:
         ! true = false
         ! false = true
    练习:写一个脚本,实现如何功能;
                (1) 用户storm不存在时,添加之;添加完成后,显示添加结果;
                (2) 否则,显示其已经存在;
    1. #!/bin/bash
    2. ! id $name && useradd $name && echo "the $name has been add"||echo "the user $name has exist"

    2.bash的配置文件

     程序:定制工作特性(命令行选项、配置文件)
     
            配置文件分三类:
                profile类:为交互式登录的shell进程实现初始化的配置文件
                bashrc类:为交互式登录的shell进程实现启动配置的配置文件;
                logout类:为交互式登录的shell进程提供终止清理功能的配置文件;
     
            根据配置文件的作用范围可分为两类:
                全局:对所有用户生效
                    /etc/profile,  /etc/profile.d/*.sh
                    /etc/bashrc
     
                    注意:仅管理员有权限修改;
     
                用户个人:仅对单个用户有效
                    ~/.bash_profile
                    ~/.bashrc
     
            配置文件的作用:
                (1) profile类
                    用于定义环境变量;
                    用于运行命令或脚本;
     
                (2) bashrc类
                    用于定义本地变量;
                    定义命令别名;
                    定义umask;
     
            shell进程的启动方式有两类:
                用户以登录方式启动(登录式shell):
                    通过终端登录用户启动的shell进程;
                    使用su -l  username或su -  username实现的用户切换;
                以非登录方式启动(非登录式shell):
                    su  username实现的用户切换;
                    图形界面下打开的命令行接口;
                    运行脚本;
     
                登录式shell:
                    /etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc
     
                非登录式shell:
                    ~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh
     
            让配置文件中新定义的配置生效的方式:
                (1) 重新启动shell进程;
                    登出而后登录;
                    exec  /bin/bash
                (2) 使用source命令执行指定文件中的代码
                    source  /PATH/TO/SOMEFILE
                    .   /PATH/TO/SOMEFILE
     
                    注意:有副作用

    3.bash脚本编程之算术运算

        算术运行符:
            +,-
            *, /
            %:取余
            **:次方
     
        算术运算格式:
            (1) let  VAR=算术表达式
            (2) VAR=$[算术表达式]
            (3) VAR=$((算术表达式))
            (4) VAR=$(expr $ARG1 $OP $ARG2)
    练习:写一个脚本,完成如下功能;
            /etc/passwd文件中的root、daemon和shutdown三个用户的id之和;
    1. #!/bin.bash
    2. n1=$(id -u root)
    3. n2=$(id -u daemon)
    4. n3=$(id -u shutdown)
    5. let sum=$n1+$n2+$n3
    6. echo $sum
    练习:求/etc/fstab、/etc/grub2.cfg和/etc/issue文件的行数之和;
    1. num1=$(wc -l /etc/fstab|grep -o '^[0-9]*>')
    2. num2=$(wc -l /etc/grub2.cfg|grep -o '^[0-9]*>')
    3. num3=$(wc -l /etc/issue|grep -o '^[0-9]*>')
    4. let num0=$num1+$num2+$num3
    5. echo $num0
    6. #或者
    7. num1=$(cat /etc/fstab | wc -l)
    求上述三个文件中的总空白行数;
    1. num1=$(grep '^$' /etc/fstab|wc -l)
    2. num2=$(grep '^$' /etc/grub2.cfg|wc -l)
    3. num3=$(grep '^$' /etc/issue|wc -l)
    4. let num0=$num1+$num2+$num3
    5. echo $num0

    4.bash脚本编程格式

    脚本文件格式:
    第一行,顶格:#!/bin/bash
    注释信息:#
    代码注释:
    缩进,适度添加空白行;
    数据类型:字符型、数值型
             弱类型:字符型

    5.bash脚本编程之算术运算

    算术运算:+,-,*,/(除),%(求余),**(乘方)
    let  VAR=expression
    VAR=$[expression]
    VAR=$((expression))
    VAR=$(expr argu1 argu2 argu3)
     
    注意:有些时候乘法符号需要转义;
    增强型赋值:变量做某种算术运算后回存至此变量中
              let i=$i+#,每次自加#
              let i+=#
    +=,-=,*=, /=, %=
    自增:
    VAR=$[$VAR+1]
    let  VAR+=1
    let  VAR++
     
    自减:
    VAR=$[$VAR-1]
    let  VAR-=1
    let  VAR--
    例1:写一个脚本
    计算/etc/passwd文件中的第10个用户和第20个用户的id号之和;
    id1=$(head -10  /etc/passwd | tail -1  | cut  -d:  -f3)
    id2=$(head -20   /etc/passwd | tail -1  | cut  -d:  -f3)
    1. #!/bin/bash
    2. n1=$(head -10 /etc/passwd | tail -1 | cut -d ":" -f3)
    3. n2=$(head -20 /etc/passwd | tail -1 | cut -d ":" -f3)
    4. let sum=$n1+$n2
    5. echo "The sum is $sum."

    5.bash脚本编程之条件测试

    条件测试:判断某需求是否满足,需要由测试机制来实现
    如何编写测试表达式以实现所需的测试:
    1.执行命令,并利用命令状态返回值来判断
           0:成功
           1-255:失败
    2.测试表达式
       test expression
       [ expression ]
       [[ expression ]]
       注意:expression两端必须有空白字符,否则为语法错误
    bash的条件测试:
    1.数值测试
    2.字符串测试
    3.文件测试

    5.1 数值测试

    数值测试:数值比较
    -eq:是否等于,[ $num1 -eq $num2 ]
    -ne:是否不等于
    -gt:是否大于
    -ge:是否大于等于
    -lt:是否小于
    -le:是否小于等于

    5.2 字符串测试

    ==:是否等于
    >:是否大于
    <:是否小于
    !=:是否不等于
    =~:左侧字符串是否能够被右侧的pattern所匹配
    -z "string":判断指定的字串是否为空;空则为真,不空则假;
    -n "string":判断指定的字符串是否不空;不空则真,空则为假;
    注意:
    (1) 字符串要加引用;
    (2) 要使用[[ ]];

    5.3 文件测试

    5.3.1 存在性测试

    -a file 
    -e file
    文件的存在性测试,存在则为真,否则为假

    5.3.2 存在型及类型测试

    -b file:是否存在并为块设备文件
    -c file:是否存在且为字符设备文件
    -d file:是否存在且为目录文件
    -f file:是否存在且为普通文件
    -h file或-L file:是否存在且为符号链接文件
    -p file:是否存在且为管道文件
    -s file:是否存在且为套接字文件

    5.3.3 文件权限测试

    -r file:是否存在且对当前用户可读
    -w file:是否存在且对当前用户可写
    -x file:是否存在且对当前用户可执行
    -u file:是否存在且对当前用户拥有suid权限
    -g file:是否存在且对当前用户拥有sgid权限
    -k file:是否存在且对当前用户拥有sticky权限

    5.3.4 其他

    文件是否有内容
    -s file:是否有内容
    时间戳:
    -N file:文件自从上一次读操作后是否被修改过
    从属关系测试:
    -O file:当前用户是否为文件的属主
    -G file:当前用户是否为文件的属组

    5.3.5 双目测试

    FILE1 -ef FILE2:file1与file2是否指向同一个文件系统的相同inode的硬链接
    file1 -nt file2:file1是否新于file2
    file1 -ot file2:file1是否旧于file2

    5.3.4 组合测试条件

    逻辑运算:
    第一种方式:
    command1 && command2
    command1 || command2
    !command
    例:[ -O file ] && [ -r file ]
    第二种方式
    expression1 -a expression2
    expression1 -o expression2
    !expression
    例:[ -O file -a -x file]
    例:将当前主机名称保存至hostName变量中;
    主机名如果为空,或者为localhost.localdomain,则将其设置为www.magedu.com;
    1. #!/bin/bash
    2. name=$(hostname)
    3. #注意:上面的括号必须有
    4. [ -z "$name" -o "$name" == "localhost.localdomain" -o "$name" == "localhost" ] && hostname www.mageedu.com || echo "the hostname is `hostname`"
    5. #先判断主机名是否为空或者为localhost.localdomain或localhost,如果为真,就设置为www.mageedu.com,后面的表达式不执行;如果为假,则第二个表达式不执行,执行第三个表达式,显示现在的主机名

    6.脚本的状态返回值

    脚本的状态返回值:默认是脚本中执行的最后一条命令的状态返回值:
    自定义状态退出码:
                exit [n]:n为自己指定的状态码
     注意:shell进程遇到exit时,机会终止,因此,整个脚本执行即为结束

    7.向脚本传递参数

    7.1 位置参数变量

    位置参数变量:myscript.sh argu1 argu2
    引用方式:$1,$2,...${10},${11},..
    轮替:shift [n]:位置参数轮替
    练习:写一个脚本,通过命令传递两个文本文件路径给脚本,计算其空白行数之和
    1. #!/bin/bash
    2. #linenum.sh

    3. n1=$(grep "^$" $1 | wc -l)
    4. n2=$(grep "^$" $2 | wc -l)
    5. let sum=$n1+$n2
    6. echo "Total blank lines is $sum."
    7. #测试
    8. /bin/bash linenum.sh -x /etc/fstab /etc/virc

    7.2 特殊变量

    $0:脚本文件路径本身
    $1:脚本参数的个数
    $*:所有参数
    $@:所有参数
    例:
    1. #!/bin/bash
    2. num1=$(cat /etc/passwd|wc -l)
    3. num2=$(cat /etc/shadow|wc -l)
    4. let sum=$num1+$num2
    5. echo $sum
    6. pwd
    7. echo "the 0 is $0"
    8. echo "the 1 is $1"
    9. echo "the * is $*"
    10. echo "the @ is $@"
    执行结果如下:

    8.bash脚本编程之用户交互:

    用户交互:通过键盘输入数据,从而完成变量赋值操作
    read [option] ... [name ...]
             -p 'prompt'
             -t timeout
    1. #!/bin/bash
    2. #
    3. echo -e "please enter your test:"
    4. read TESTREAD
    5. echo $TESTREAD
    6. #下面是测试结果:
    7. [root@zhangpf test]# /bin/bash -x ceshi.sh
    8. + echo -e 'please enter your test:'
    9. please enter your test:
    10. + read TESTREAD
    11. abc
    12. + echo abc
    13. abc
    bash -n /path/to/some_script
            检测脚本中的语法错误
     
        bash -x /path/to/some_script
            调试执行
    例:执行脚本,可以添加用户,并进行设置密码,如果用户名已经存在就进行提示,如果没有此用户就添加
    1. #!/bin/bash
    2. #
    3. read -p "please enter a username: " name
    4. [ -z "$name" ] && echo "a username is needed." && exit 2
    5. read -p "please enter a passwd for $name ,[passwd]: " password
    6. [ -z "$password" ] && password="password"
    7. if id $name &>/dev/null;then
    8. echo "The user $name exists."
    9. echo "The user id is `id -u $name`"
    10. else
    11. useradd $name
    12. echo "$password" | passwd -stdin $name &>/dev/null
    13. echo "The user $name finished."
    14. fi
  • 相关阅读:
    深入理解 C/C++ sizeof() 运算符
    Luogu2040 | 打开所有的灯 (广搜+状压)
    Intel 8086 标志寄存器及JCC指令表
    Intel 8086 常用汇编指令表
    PTA L2-029 | 特立独行的幸福 (打表+递归)
    C++中为什么要用指针,而不直接使用对象?
    c#中基本类型占用字节数
    c++TXT文件读入
    较为初始的学生成绩管理系统
    C++中各种数据成员及成员函数的定义及使用
  • 原文地址:https://www.cnblogs.com/zhangpf/p/5657380.html
Copyright © 2011-2022 走看看