bash shell脚本编程学习总结

shell脚本编程

编译器-------解释器
静态语言:编译型语言,强类型(变量);事先转换成可执行格式。C/C++/JAVA/C#
动态语言:解释型语言,弱类型。边解释变执行。PHP,SHELL,python,perl
面向过程:shell,c;面向对象:java,python,perl,c++
变量赋值:VAR_NAME = VALUE;

bash变量类型:
    环境变量:作用域为当前shell进程及其子进程。
        export VARNAME=VALUE或者 VARNAME=VALUE export VARNAME "导出"定义为环境变量。
        脚本在执行时候启动一个子shell进程:
        [[email protected] ~]# NAME=LINJUNBIN
        [[email protected] ~]# export NAME
        [[email protected] ~]# echo $NAME
        LINJUNBIN
        [[email protected] ~]# bash   //切换到子shell;
        [[email protected] ~]# echo $NAME  //该环境变量依然有效。
        LINJUNBIN

    本地变量(局部变量):
        整个bash进程:本地变量:VARNAME=VALUE
        局部变量:作用域为当前代码段有效。local VARNAME=VALUE
    位置变量:
        $1,$2,....
    特殊变量:(bash内置):$?:上一个命令的执行状态返回值状态值;
        程序执行一般有两种返回值;执行状态$?=0-255
        0:正确执行;1-255:错误执行;
        1,2,127:系统预留。
        $?:上次命令执行返回状态码;
        $#:参数的个数
        $*:参数列表
        [email protected]:参数列表            

引用变量:${VAR_NAME},引用该变量。
    [[email protected] ~]# echo "there are some ${ANIMAL}s."
    there are some PIGs.
    [[email protected] ~]# echo ‘there are some ${ANIMAL}s.‘
    there are some ${ANIMAL}s.
    注意:‘‘单引号和""双引号的区别。

输出重定向:
    >:>>:2>:2>>,&>
输入:
    /dev/null:软件设备;/dev/null:数据黑洞;
    eg:判断是否含有某个用户。
        [[email protected] ~]# id student &> /dev/null
        [[email protected] ~]# echo $?
        1
撤销变量:
    unset VARNAME不用加$;
查看变量:
    使用set命令;set:包含环境变量和本地变量;
    查看环境变量:printenv ,env, export;三个都可以。
eg:
    [[email protected] ~]# ANIMALS=pig
    [[email protected] ~]# ANIMALS=$ANIMALS:goat
    [[email protected] ~]# echo $ANIMALS
    pig:goat
脚本:命令的堆砌,
判断用户是否存在:id user1 &> /dev/null && echo "hello user1";
    [[email protected] test]# id root &> /dev/null && echo ‘root‘
    root

shell条件判断

判断执行结果$?来判断执行的状态码来判断执行是否成功或者失败。
整数测试:
    -eq:测试两个整数是否相等;
    -ne:测试两个整数是否不等,不等,为真;相等,为假;
    -gt:测试一个数是否大于另一个数;
    -lt:测试一个数是否小于另一个数;
    -ge:大于或者等于;
    -le:小于或者等于;
    eg:
            [[email protected] test]# A=3
            [[email protected] test]# B=4
            [[email protected] test]# [ $A -eq $B ]
            [[email protected] test]# echo $?
            1
            [[email protected] test]# B=3
            [[email protected] test]# [ $A -eq $B ]
            [[email protected] test]# echo $?
        0
字符测试:
文件测试:

条件测试表达式:注意:两边要空格。
    [ expression表达式 ],[[ expression ]] , test expression
表达式:

命令间的逻辑关系;
    逻辑与:&&,第一个条件为假第二个条件不用执行,两个都必须为真。
    逻辑或:|| 第一个条件为假,第二个条件必须得判断。两个中一个为真就可以。
    eg:如果用户user6不存在,就添加用户user6
        ! id user6 &> /dev/null && useradd user6
        id user6 &> /dev/null || useradd user6
LINE=`wc -l /etc/inittab`;将这个命令运行结果放在变量中。
eg:如果文件/etc/inittab文件的行数大于100,就显示好大的文件,否则显示小文件。
        [[email protected] test]# cat souce.sh
        #!/bin/bash
        LINES=`wc -l /etc/inittab`
        echo $LINES
        FINLINES=`echo $LINES | cut -d‘ ‘ -f1`
        echo $FINLINES;    

        [ $FINLINES -gt 100 ] && echo "/etc/inittab is a big file." || echo "/etc/inittab is a small file"

        [[email protected] test]# bash souce.sh
        17 /etc/inittab
        17
        /etc/inittab is a small fi

eg:为系统添加用户:
`! id user1 &> /dev/null && useradd user1 && echo "user1" | passwd --stdin user1 &> /dev/null || echo ‘user1 exists`
    添加完用户,管道到passwd。进行设置密码;同时输出总行数。
    [[email protected] test]# bash addUser.sh
    user1 exists
    39
    [[email protected] test]# cat addUser.sh
    #!/bin/bash
    ! id user1 &> /dev/null && useradd user1 && echo "user1" | passwd --stdin user1 &> /dev/null || echo ‘user1 exists‘
    ! id user2 &> /dev/null && useradd user2 && echo "user2" | passwd --stdin user2 &> /dev/null || echo ‘user2 exists‘
    ! id user3 &> /dev/null && useradd user3 && echo "user3" | passwd --stdin user3 &> /dev/null || echo ‘user3 exists‘
    #获取总行数
    LINES=`wc -l /etc/passwd | cut -d‘ ‘ -f1`
    echo $LINES;

    eg:
    #判断当前用户是否为root用户;
            [[email protected] test]# bash is_root.sh
            is root
            [[email protected] test]# cat is_root.sh
            #!/bin/bash
            USER_UID=`id -u`;
            [ $USER_UID -eq 0 ] && echo ‘is root‘ || echo "is not root and this uid is ${UID}"
        注意:报错is_root.sh: line 2: UID: readonly variable,原来是UID变量设置和环境变量重名,主要变量命名。

if条件判断

单分支的if语句:
    if 判断条件
    then
        statement1;statement2;
    fi
双分支if语句:
    if 判断条件; then
        statement1;statement2;...
    else
        statement3;statement4;...
    fi
多分支if语句
    if 条件判断1; then
        statement1;...
    elif 判断条件2; then
        statement2;...
    elif 判断条件3; then
        statement3;...
    ...
    else
        statement4;...
    fi

eg:
    #判断某个用户是否存在:
    [[email protected] test]# bash user.sh
    user12 IS NOT exists
    [[email protected] test]# cat user.sh
    #!/bin/bash
    NAME=user12;
    if id $NAME &> /dev/null; then
    echo "$NAME is exists"
    else
    echo "$NAME IS NOT exists"
    fi
    #如果用户存在就显示存在,如果不存在就进行添加;

eg:
#判断当前系统是否有用户的默认shell为bash:如果有,就显示多少个,否则就显示没有这类用户
        [[email protected] test]# ./is_bash.sh
        the shells of 10 users is bash shell
        [[email protected] test]# cat is_bash.sh
        #!/bin/bash
        #获取默认的shell为bash
        grep "bash$" /etc/passwd &> /dev/null;
        RETVAL=$?;
        if [ $RETVAL -eq 0 ]; then
          USERS=`grep "\<bash$" /etc/passwd | wc -l`
          echo "the shells of $USERS users is bash shell";
        else
         echo "no bash user"
        fi
        [[email protected] test]# 

#验证/etc/inittab这个文件有没有空白行,多少空白行
        [[email protected] test]# cat has_space.sh
        #!/bin/bash
        grep "^$" /etc/inittab &> /dev/null;
        HAS_SPACE=$?
        if [ $HAS_SPACE -eq 0 ] ; then
        SPACES=`grep "^$" /etc/inittab | wc -l`;
        echo "total SPACES is $SPACES LINES";
        else
        echo "no any spaces in /etc/inittab";
        fi
        [[email protected] test]#
    注意:等号两边不能有空格;

#验证用户的uid是否等于GID,两种实现方式
        [[email protected] test]# cat uid_eq.sh
        #!/bin/bash
        USERNAME=user1
        #USERID=`id -u $USERNAME`;
        USERID=`grep "^user1" /etc/passwd | cut -d: -f3`
        GROUPID=`grep "^user1" /etc/passwd | cut -d: -f4`
        #GROUPID=`id -g $USERNAME`;

        if [ $USERID -eq $GROUPID ] ; then
        echo ‘Good guy‘;
        else
        echo ‘Bad guy‘;
        fi
#注意:date +%s表示时间戳中1970开始的秒数;man date
echo $HISTSIZE;

#给定一个文件测试其是否存在
#单步执行;bash -x
    eg:测试脚本的执行过程。bash -x
        [[email protected] test]# bash -x file_test.sh
        + FILE=/etc/inittab
        + ‘[‘ -e /etc/inittab ‘]‘
        + echo OK
        OK
        [[email protected] test]#

#给定一个文件,如果是否普通文件,就显示,如果是目录就显示,否则显示无法辨别该文件。
    [[email protected] test]# ./file_test.sh
    common file
    [[email protected] test]# cat file_test.sh
    #!/bin/bash

    FILE=/etc/inittab

    if [ ! -e $FILE ]; then
    echo ‘no such file‘;
    exit 6;
    fi
    if [ -f $FILE ]; then
    echo ‘common file‘;
    elif [ -d $FILE ]; then
    echo ‘directory‘;
    else
    echo ‘unknown‘;
    fi
    注意:判断符!后面必须要有空格;

shell中进行算术运算

shell中默认所有的变量都是字符串;
    [[email protected] test]# A=3
    [[email protected] test]# B=4
    [[email protected] test]# echo $A+$B
    3+4
一般使用1,2,3这三种方法:
1、算术运算let:
    let C=$A+$B
2、$[算术运算表达式]
    C=$[$A+$B]
3、$((算术运算表达式))
    C=$(($A+$B))
4、expr 算术运算表达式,表达式中各操作数和运算符之间要有空格,而且使用命令引用
    F=`expr $A + $B`
5、使用运算器bc

退出脚本

exit:退出脚本;
exit n;n为退出状态码;
如果脚本没有明确定义退出状态码,那么,最后一条命令的退出码即为脚本的退出状态码;

测试方法

使用中括号测试法:
[ expression ]:两边记得要用空格,命令测试法;
[[ expression ]]:关键字测试法;
test expression:
只有使用-gt,-le,-ne,-eq,-ge,-lt:需要加上中括号,其他的不一定需要加中括号。
if `grep "^$USERNAME\>" /etc/passwd` ; then

文件测试:
    -e FILE:文件是否存在。
    -f FILE:测试文件是否为普通文件
    -d FILE:测试指定路径是否为目录;
    -r FILE:测试当前用户对指定文件是否有读权限
    -w FILE:测试当前用户对指定文件是否有写权限
    -x FILE:测试当前用户对指定文件是否有执行权限
    eg:
    [ -e /etc/inittab ] ,[ -x /etc/rc.d/rc.sysinit ]
        [[email protected] test]# ./exitst_file.sh
        NO /etc/iniittab
        [[email protected] test]# cat exitst_file.sh
        #!/bin/bash

        FILE=/etc/iniittab
        if [ ! -e $FILE ] ; then
          echo "NO $FILE"
          exit 8;
        fi

圆整:丢弃小数点后面内容;/
显示历史命令:
    [[email protected] test]# history | tail -1 | cut -d‘ ‘ -f2
    1012

位置变量(参数)

位置变量$1,$2,...
./file_test.sh /etc/fstab /etc/inittab;
$1:/etc/fstab;   $2:/etc/inittab;
shift:将参数列表中第一个参数弹出;相当于数组中的shift弹出第一个元素;
shift n:表示一次弹出n个参数;

#判定:接收一个参数,如果一个存在的文件就显示OK,如果不存在就显示no such file
    eg:$#:显示所有参数个数;$*:参数列表 [email protected]:参数列表;
            [[email protected] test]# ./exitst_file.sh /etc/inittab /ffff /ttddd
            3
            /etc/inittab /ffff /ttddd
            /etc/inittab /ffff /ttddd
            OK
            [[email protected] test]# cat exitst_file.sh
            #!/bin/bash
            echo $#
            echo $*
            echo [email protected]

            if [ ! $1 ]; then
             echo ‘please add parame file‘;
            exit;
            fi

            if [ -e $1 ] ; then
              echo "OK"
            else
              echo "no such file";
            fi
            [[email protected] test]#

#测试shift
        [[email protected] test]# ./shift.sh 1 2 3 4 5
        5
        1
        2
        4
        [[email protected] test]# cat shift.sh
        #!/bin/bash

        echo $#;
        echo $1;
        shift
        echo $1;
        shift 2
        echo $1
时间: 2024-10-10 20:22:59

bash shell脚本编程学习总结的相关文章

8.11_Linux之bash shell脚本编程入门篇(一)

什么是bash shell脚本编程? 答:Linux里面有多种shell,而CentOS和redhat的默认shell是bash shell.至于shell脚本,这个跟windows操作系统里面的批处理文件有点像(.bat的文件).不知道大家还是否记得Linux的哲学思想吗?其中有那么两点点:由众多目的的单一应用程序组成:一个程序只做一件事,且做好:组合目的的单一的小程序完成复杂的任务.我觉得shell脚本编程就很好的体现了这个哲学思想.shell脚本利用shell的功能缩写的一个"程序&quo

Linux Shell脚本编程学习笔记和实战

http://www.1987.name/141.html shell基础 终端打印.算术运算.常用变量 Linux下搜索指定目录下特定字符串并高亮显示匹配关键词 从键盘或文件中获取标准输入 [read命令] 文件的描述符和重定向 数组.关联数组和别名使用 函数的定义.执行.传参和递归函数 条件测试操作与流程控制语句 获取时间日期格式和延时 [date.sleep命令] 内部字段分隔符IFS和脚本的调试DEBUG 显示.读取或拼接文件内容 [cat命令] 文件查找与打印文件列表 [find命令]

Bash Shell脚本编程笔记总结(一)

本文是上课笔记总结,涉及细节知识点会在以后文章说明! bash脚本编程: 脚本程序:解释器解释执行: shell: 交互式接口:编程环境: shell: 能够提供一些内部命令,并且能通过PATH环境变量找到外部命令:把命令提交给内核启动为进程: 编程环境: 流程控制语句: 顺序执行: 循环执行: 选择执行: 条件测试:真.假 $? 命令的状态结果: 0: 真 1-255: 假 过程式的编程语言的元素:变量.流程.函数.数组 变量:局部变量.本地变量.环境变量.位置参数变量.特殊变量 变量: 数值

Bash Shell脚本编程笔记总结(二)

本文接上一部分:Bash Shell脚本编程笔记总结(一) 数组: 连续的多个独立内存空间,每个内存空间相当于一个变量 数组元素:数组名+索引 索引:从0开始编号 声明数组: declare -a ARRAR_NAME 关联数组: declare -A ARRAY_NAME 支持稀疏格式: 数组元素的赋值: (1) 一次只赋值一个元素 ARRAY[index]=VALUE a[0]="hello" (2) 一次赋值全部元素 ARRAY=("mon" "tu

8.15_Linux之bash shell脚本编程入门篇(二)以及文件查找和压缩的使用

bash shell脚本编程入门篇(二) read命令的使用 作用: 使用read来把输入值分配给一个或多个shell变量: -p指定要显示的提示 -t TIMEOUT read从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量 EX.read -p "Enter a filename:" FILE 条件选择之if的使用 if的作用:选择执行(注意:if语句可嵌套) 单分支 if 判断条件;then 条件为真的分支代码 fi EX.单分支案例 双分支 if

8.17_Linux之bash shell脚本编程入门篇(三)之循环以及函数function的使用

bash shell脚本编程入门篇(三)之循环 什么是循环执行? 将某代码段重复运行多次 重复运行多少次: 循环次数事先已知 循环次数事先未知 有进入条件和退出条件 相关命令:for, while, until,selet, for命令的使用 作用: 依次将列表中的元素赋值给"变量名"; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束 命令格式: for 变量名 in 列表; do 循环体(正常执行的执行命令) 语句1 语句2 语句3 ... done 列表生成方式: (

在Bash shell脚本编程中,如何正确无误获取到“脚本选项参数”和“脚本参数”呢?

Linnux 中有些命令的功能非常强大,主要是因为它支持的命令选项比较多.如:[ip]命令可以配置IP地址.路由条目的配置管理操作非常完善,该命令就可以完成[ifconfig]和[route]命令实现的所有功能.函数是单独的功能模块,如果函数能够接收选项参数,那么该函数的功能就变得丰富,且灵活.脚本也是一样. 那么linux中命令的格式又是怎么样的呢? [[email protected] ~]# command   [optons parameter1 | parameter2]...  pa

shell脚本编程学习笔记(1)

在linux上编程,离不开shell,计划好好看看shell编程,并在这里做些笔记以供有相同兴趣的人分享,主要参考<shell脚本学习指南>. 学习shell脚本编程之前,需要了解脚本编程语言和编译型语言的概念. 一般很多中型.大型的程序是用编译型语言写成的,比如C.C++.Java等.这类程序从源代码编译成目标代码,直接通过计算机执行.编译型语言执行效率比较高,大多运作于底层,处理的是字节.整数.浮点数等机器层级的对象,因此实现一个具体的功能,比如"将一个目录里的所有文件复制到另外

源码时代Java干货分享|Shell脚本编程学习入门,只需两个步骤,包你学会!

最近在学习shell编程,对于shell脚本中第一行用于指定脚本解释器的代码到底有没有起到指定解释器的作用感到疑惑,如:#!/bin/bash 在网上查找了不少资料,发现网上竟然也分了两大派,一些人认为#!/bin/bash没有起到作用,因为在shell脚本中#表示是注释的意思,而另一些人则认为是起作用的,但是没有给出令人信服的理由,没办法,我只好自己动手做测试了.1.首先我先创建了一个名为test.sh的shell文件,里面内容如下 这个脚本文件中的第二行代码使用了bash语法,不支持POSI