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
原文地址:https://www.cnblogs.com/zhangpf/p/5657380.html