zoukankan      html  css  js  c++  java
  • 【 编程语言 】Shell学习记录

    基础编程
        1. 创建
            在文件的第一行指定要使用的运行方式      #!/bin/bash
            系统会按照第一行!后指定的运行方式运行整个文件内容。
            如果不写的话,系统可能会按照当前登录的shell执行,但只是可能,Ubuntu系统很可能出问题。
            所以第一行指定运行方式是一种良好的习惯。
        2. 显示与输入
            输入
                read命令     等待用户的输入,并将获取的数据存到一个变量中
                    read -p “Enter your name: ”name
                    其他参数:
                        -t     指定超时时间
                        -s     隐藏方式读取
            显示
                echo “hello world”            自动动添加换行符
                    控制输出不换行:        -n 参数
                    让特殊转义符起作用        -e 参数
                        转义符一览
                             其后有字符时,作为退格键
                            c 取消输出行末的换行符
                            e ESCAPE 键
                            f 换行后连接上一行的结尾
                            v 垂直制表符
                             换行符
                             光标移至行首
                             制表符,也就是 Tab 键
                printf “hello %s %f ” world 11.11        不自动换行,需要手动加 ,使用类似C语言printf
                    printf  可以使用%对输出间距进行控制 使用间距控制,我们不用再担心显示输出时因变量长度的不确定性导致的混乱问题
                        %-10s        左对齐,显示宽度为10个字符的字符串,不足使用空格补齐
                        %10s        右对齐,显示宽度为10个字符的字符串,不足使用空格补齐
                        %10.2f        右对齐,显示宽度为10个字符的浮点数,小数点后面保留两位
            
            重定向
                输入和输出进程在Linux也是以文件的概念存在
                Linux用文件描述符来标识每个文件对象,它是一个非负整数
                每个进程一次最多可以有九个文件描述符(可以理解为指针变量),而bash shell保留了前3个。
                    文件描述符        缩写            描述
                        0            STDIN            标准输入
                        1            SIDOUT            标准输出
                        2            SIDERR            错误输出
                符号(可以理解为把符号左边的内容传送到右边)
                    覆盖    >
                    追加    >>
                临时重定向与永久重定向
                    临时
                        将标准输出重定向到文件    Command    >    file
                        将错误输出重定向到文件    Command    2>    file
                        将所有输出重定向到文件    Command >file 2>file    或者    Command &>file
                    永久
                        exec命令:        exec 1>file
                        exec命令会在脚本执行期间保持设定的重定向策略
                        永久重定向之后想再改回来怎么办?可以使用后6个自定义文件描述符
                            exec 3>&1
                            exec 1>file
                            exec 1>&3
                既要显示又要存到文件
                    tee filename        覆盖
                    tee –a filename     追加    
            高级显示控制    使用SGR转义码
                格式为                 CSI[nm
                CSI 代表转义标志字符
                    实际上就是ESC的ASCII值
                    产生方法:
                        Linux下编辑时的产生方法
                            Ctrl+v 后按 ESC            Linux系统显示为 ^[
                        非Linux下编辑时的产生方法
                            33                echo 需配合-e参数
                            echo -e  "hello 33[31;47mworld33[0m"
                m 代表此语句为SGR转义码
                [ 半中括号为固定格式作为分隔
                n 代表控制码,可以有多个,使用 ; (分号)进行分隔
                        效果控制码                                                  颜色控制码
                        代码    描述                                                 两    代码    描述
                        0        重置为普通模式                                位    0        黑色
                        1        设置为强亮度                                    数    1        红色
                一    2        设置为弱亮度                                    3x    2        绿色
                位    3        使用斜体                                      前    3        黄色
                数    4        使用单下划线                                    景    4        蓝色
                字    5        使用慢闪烁                                       4x    5        洋红色
                        6        使用快闪烁                                       背    6        青色
                        7        背景色和前景色反转                         景    7        白色
                        8        将前景色设置为背景色(文字不可见   色
        3. 变量
            使用变量的方法:
                1. $variable        美元符号后紧跟变量名
                2. ${variable}        使用大括号
                以上两种方法没有本质区别。
                    使用大括号的优点是:可以在调用变量后紧跟字符
                    比如:        $ab        表示变量ab的值,而${a}b 表示变量a的值后紧跟b字符
            命令替换:
                1. $( )            美元符号后加小括号
                2. ``            反引号
                小括号和反引号中的字符会作为运行命令,其输出值作为返回值。
                
            环境变量:
                存储有关shell会话和工作环境的信息。
                这项特性允许你在内存中存储数据,是存储持久数据的一种简便方法。
            用户自定变量:
                定义方法:
                    变量名=value        变量名='value'        变量名="value"
                注意事项:    等号两边不能有空格
            特殊变量:
                $0                执行时脚本本身的路径与名称
                $1 ~ $n            表示脚本的第n个参数
                $#                脚本运行时携带的命令行参数的个数
                $*                脚本的所有参数组成一个单词
                $@                脚本的所有参数当做一个字符串的独立单词
                $?                上一个命令的执行状态
                $$                脚本运行的当前进程的ID号
                $!                后台运行的最后一个进程的ID号
            局部变量
                使用普通方式定义的变量都是全局变量
                如果要在函数中定义局部变量,需要使用 local 关键字
            数组
                定义方法:
                    array=(one two three four five)
                使用:
                    echo “${array[2]}”
                删除:
                    删除单个值         unset  ${array[2]}
                    删除整个数组     unset  array  
        4. 结构化命令
            if命令
                if command            或     if command;then
                then                
                    command                    
                elif                或    elif;then
                    command
                else
                    command
                fi
                Command 部分是Linux下的命令,而if测试的是此命令执行完毕的退出码
                使用格式     test condition        可以测试其他的条件,比如数值比较之类
                    linux提供了test命令的简便用法    [(空格)  待比较条件 (空格)] 代替test命令
                    使用示例:
                        If [ $a –eq 1 ]
                    condition部分分类
                        数值比较            
                        -eq                         等于
                        -ne                         不等于
                        -gt                          大于
                        -lt                           小于
                        -ge                         大于等于
                        -le                          小于等于
                        
                        字符串比较
                        -z Str                          “Str” 的长度为零则为真。 [ -z "$aaa" ] [[ -z $aaa]]
                        [ -n Str ] or [ Str ]        “Str” 的长度为非零 non-zero则为真。
                        [ Str1 == Str2 ]            如果2个字符串相同则为真。
                        [ Str1 != Str2 ]             如果字符串不相等则为真。
                        [ Str1 < Str2 ]              如果 “Str1” sorts before “Str2” lexicographically in the current locale则为真。
                        [ Str1 > Str2 ]              如果 “Str1” sorts after “Str2” lexicographically in the current locale则为真。
                        
                        文件比较
                        -a FILE             如果 FILE 存在则为真
                        -b FILE             如果 FILE 存在且是一个块文件则为真。
                        -c FILE             如果 FILE 存在且是一个字特殊文件则为真。
                        -d FILE             如果 FILE 存在且是一个目录则为真
                        -e FILE             如果 FILE 存在则为真
                        -f FILE              如果 FILE 存在且是一个普通文件则为真
                        -g FILE             如果 FILE 存在且已经设置了SGID则为真。
                        -h FILE             如果 FILE 存在且是一个符号连接则为真
                        -k FILE             如果 FILE 存在且已经设置了粘制位则为真
                        -p FILE             如果 FILE 存在且是一个管道则为真
                        -r FILE             如果 FILE 存在且是可读的则为真
                        -s FILE             如果 FILE 存在且大小不为0则为真
                        -t FD                如果文件描述符打开且指向一个终端则为真
                        -u FILE             如果 FILE 存在且设置了SUID则为真
                        -w FILE             如果 FILE 存在且是可写的则为真
                        -x FILE             如果 FILE 存在且是可执行的则为真
                        -O FILE             如果 FILE 存在且属有效用户ID则为真
                        -G FILE             如果 FILE 存在且属有效用户组则为真。
                        -L FILE             如果 FILE 存在且是一个符号连接则为真
                        -N FILE             如果 FILE 存在并已经被修改 如果ied since it was last read则为真
                        -S FILE             如果 FILE 存在且是一个套接字则为真。
                        FILE1 -nt FILE2     如果 FILE1比FILE2新或 FILE1 存在 FILE2 不存在则为真
                        FILE1 -ot FILE2     如果 FILE1 比 FILE2 要老,或者 FILE2 存在 FILE1 不存在则为真
                        FILE1 -ef FILE2     如果 FILE1 和 FILE2 指向相同的设备和节点号则为真
                复合条件测试: []&&[]    []||[]
                双括号    (( expression ))
                    Expression 中除了支持之前提到的比较运算符,还提供了如下预算符
                    val++        后增
                    val--        后减
                    ++val        先增
                    --val        先减
                    !            逻辑求反
                    ~            位求反
                    **            幂运算
                    <<            左移
                    >>            右移
                    &            按位与
                    |            按位或
                    &&            逻辑与
                    ||            逻辑或
                双方括号 [[ expression ]]
                    提供了字符串比较的高级特性
                    特殊字符不需要转义( >, >>, <, <<等  )
                    可以进行模式匹配
                        if [[ $USER == r* ]]
            case命令
                case variable in
                pattern1 | pattern2)
                    commands0
                    commands1;;
                pattern3)
                    commands2;;
                *)
                    commands;;
                esac
                
                注意事项:
                    选项列表使用右半括号    )
                    每个选项下的最一条命令后用两个分号作为结束    ;;
                    Case结束之后使用esac结尾
            for命令
                for var in list
                do
                commands
                done
                注意事项:
                    list参数:需要迭代的一系列值,
                    在每次迭代时,var等于列表中的当前值
                    最后一次迭代完成之后,var会保留最后的迭代值
            while命令
                while test command
                do
                other commands
                done
                意义:
                    只要成立,就循环0
                注意事项:
                    test command中可以有多个命令,但是只把最后一个命令的返回值作为判断条件
                    Test command和if 命令中一模一样,不做解释
            until命令
                until test commands
                do
                other commands
                done
                意义:
                    只要成立,就停止,否则就循环
        5. 函数
            创建
                function    func1 {
                commands
                }
                
                func2() {
                commands
                }
                和C语言的函数一样,使用函数需在定义函数后
                同名函数会覆盖之前的定义,没有报错
            运行
                bash shell会把函数当做小型脚本执行,运行结束之后会返回一个退出状态码
            函数退出
                退出状态码有三种生成方式
                    默认退出状态码
                        函数中最后一条命令返回的退出状态码
                        使用特殊变量$? 获取
                    使用return命令
                    直接获取函数的输出
            函数入参
                函数传入参数的方法和给shell脚本传入参数的方法是一样的
                作为入参的特殊变量是局部的,只在函数内部起作用。
                shift命令会根据它们的相对位置来移动命令行参数,移出的参数值被丢弃
                    当你不知道到底有多少参数时,可以使用shift命令,只需操作第一个参数
                    $0 不会被移动。
    高级编程
        shell父子关系
            我们在登录某个linux终端时,默认是以命令行的形式,这个命令行就是一个shell提供的CLI提示符
                我们在CLI提示符后输入的命令,都是由当前shell去执行。
            那么,如果我们再输入一个bash命令,或者其他的shell命令,会怎么样呢?
                其实bash命令已经重新创建了一个shell,我们需要借助ps命令查看。
                我们称新建立的shell为子shell,原来的shell为父shell。
            子shell仍然可以继续建立子shell。
            需要注意的是
                生成子shell的成本不低,速度还很慢,子子孙孙的嵌套更是很占用资源。
                在生成子shell时,只有部分父进程环境被复制到子shell环境中。
                其他诸如协程、进程列表相关内容,请自行学习。
        脚本控制-信号
            进程的信号就是预定义好的一个消息,进程能识别它并决定忽略还是作出反应。
            Linux利用信号与运行在系统中的进程进行通信,包括停止、启动、终止进程等等。
            有哪些信号:
                信号    值            描述                            简单描述
                1        SIGHUP        挂起进程                        
                2        SIGINT        终止进程                        Ctrl + C
                3        SIGQUIT        停止进程
                9        SIGKILL        无条件终止进程
                15        SIGTERM        尽可能终止进程
                17        SIGSTOP        无条件停止进程,但不是终止
                18        SIGTSTP        停止或暂停进程,但不终止        Ctrl + Z
                19        SIGCONT        继续运行停止的进程
            Ctrl + Z暂停进程后恢复的方法
                jobs 查看当前暂停的进程
                bg %N     将第N个进程恢复到后台
                fg  %N     将第N个进程恢复到前台
            其他信号:
                Ctrl + S : 锁定屏幕
                Ctrl + Q : 恢复显示
            信号捕获        我们可以主动捕获到上述信号并执行其他的命令
                Trap命令:
                    启动捕获 :     Trap commands signals
                    移除捕获 :    Trap --(-) signals
        有助于脚本调试的方法
            -n         不要执行脚本,仅检查语法错误
            -v        在执行脚本前,先将脚本内容输出到屏幕上。
            -x        将执行到的脚本语句,输出到屏幕上。
    其他常用方法
        在脚本中读入文件
            有时,在脚本中使用管道等处理大量文件时不够方便
            我们可以将要处理的数据存入文件中,然后一行一行的读出来处理。
            本质:while 和 read 命令的高级使用方法。
                while read line
                do
                    echo $line
                done < "./file"
            重要的原则
                重定向,必须在尾部
                对循环重定向的输出,可适用于循环中所有需要向标准输出写数据的命令。
                对循环重定向的输入,可适用于循环中所有需要从标准输入读数据的命令。
                当在循环内部显式的使用重定向时,内部重定向覆盖外部重定向。
        创建选单
            本质:    select 与 case 的配合使用
            Select :     向用户提供选项,供用户选择。将选择结果        的字符串存入变量中。
            PS3 :     使用select时的提示符
                PS3="Enter option: "
                select option in "one" "exit" ;
                do
                    case $option in
                        "one")
                                echo -e " select one "
                                ;;
                        "exit")
                                break
                                ;;
                    esac
                done
        脚本参数补全
            原理
                Compgen –W        - 从选单中匹配候选单词列表
                    complete        - 说明命令如何进行补全
                    -F        指定执行函数名 , 候选结果保存在COMPREPLY变量中
                    -f        补全文件名
                    -X        过滤表达式
                    -o        补全类型(filenames, dirnames)
            示例
                complete -o default -F _test_tab_func test.sh

                _test_tab_func()   
                {
                    local cur prev opts
                    
                    COMPREPLY=()
                        
                    cur="${COMP_WORDS[COMP_CWORD]}"  
                    prev="${COMP_WORDS[COMP_CWORD-1]}"  
                    opts="-help -usage -version -vvv "                  
                            
                    if [[ ${cur} == * ]];then
                        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
                        return 0
                    fi  
                }
            生效方法
                将刚才编写的代码,加入~/.bashrc 等(不推荐)
                将上述代码,写入/etc/bash_completion.d/下,与命令名相同的脚本中。

                













                    
        
        
       

  • 相关阅读:
    Redis Pipeline原理分析
    python 装饰器,传递类以及参数
    q
    Redis的EXPIRE过期机制介绍
    z
    julia .文档
    julia 安装
    python 弧度与角度互转
    python 角度和弧度转化
    机器人行业中我们常说的roll、yaw、pitch是什么?
  • 原文地址:https://www.cnblogs.com/guoqingpeng/p/14720910.html
Copyright © 2011-2022 走看看